首页 > 学院 > 开发设计 > 正文

leecode 解题总结:123. Best Time to Buy and Sell Stock III

2019-11-08 19:24:53
字体:
来源:转载
供稿:网友
#include <iostream>#include <stdio.h>#include <vector>using namespace std;/*问题:Say you have an array for which the ith element is the PRice of a given stock on day i.Design an algorithm to find the maximum profit. You may complete at most two transactions.Note:You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).分析:至少要交易两次,求取至少交易两次下的最大值。因为无法确定到底交易多少次。也有可能一直在亏损,那么就要选取亏损较少的时候。这个有点类似于广度优先搜索求解最优,但这个是如果是暴力破解:没办法破解,因为至少两次,至多只有n-1次,应该是一个动态规划问题。设dp[i]表示截止到天数i获得的最大利润。B[i]表示最近一次抛售股票的日期,那么dp[i+1]要么是还等于dp[i],记j=B[i],从j到天数i+1中选择出一个两天,组成一次交易并且有maxNum = 0;maxNum = max( A[i+1] - A[j] , maxNum ),其中j 属于[ B[i] , i ]如果maxNum > 0,那么又选择了j和i+1作为一次新的交易设计一个计数器cunt,每次组成新的交易,累加,目标是dp[n],先计算第一遍,求出dp[n],如果count = 0,说明没有选择交易,说明整个是降序的,那么遍历一遍,选择两次:两个差值最大的(实际比如9 7,和9 4,两个查实分别为-2,-5,应该选择-2)如果count = 1,说明还缺少一次交易,则根据之前一次记录的交易截止天数i,从i到n开始都是降序,那么就寻找两个差值最大的如果count >= 2,直接返回结果似乎还是不对。看答案:leecode:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/?tab=Solutions需要维护一个通过k次交易,到达prices[i]时候的最大利润,也就是记录了:交易次数,交易截止日期i,以及最大利润三个变量【关键】我没想到是记录交易次数,但题目说了交易次数,就应该把其抽象为要记录的变量设dp[k][i]表示截止到prices[i],通过k次交易,所能得到的最大利润,不包括第prices[i],八这个变量需要留作下一次使用第k次得到最大利润,等于截止到日期j,通过k-1次得到最大的利润,加上prices[j] - prices[i]的利润 和 不需要包含当前这个元素的利润dp[k-1][i-1]的最大值中的其中一个,漏了dp[k][i]= max(dp[k][i-1], dp[k-1][j] + prices[i] - prices[j] ),其中j属于[]dp[0][i] = 0,表明通过0次想要赚得的最大利润为0dp[k][0]= 0,表明如果仅有一个价格prices[0],那么获得的最大利润为02//dp[0][i] = 0//dp[k][0] = 0,所以无需再初始化//dp[k][i] = max( dp[k][i-1] , dp[k-1][j] + prices[i] - prices[j] ),j属于[0 , i-1]//         = max ( dp[k][i-1], prices[i] + max(dp[k-1][j] - prices[j]),牛逼,把常量全部提取出来//目标值dp[2][n-1]int maxProf = 0;for(int k = 1 ; k <= K ; k++)//这里限定k的结果,必须从1开始因为后面有k-1{	int tempMax = dp.at(k-1).at(0) - prices.at(0);	for(int i = 1; i < size ; i++)//下标从1开始	{		dp.at(k).at(i) = max( dp.at(k).at(i-1) , prices.at(i) + tempMax );		//牛逼把常量拆分出来,最大值通过一次遍历即可,无需再次开一个循环		tempMax = max(tempMax , dp.at(k-1).at(i) - prices.at(i));		maxProf = max(maxProf, dp.at(k).at(i));	}}*/class Solution {public:    int maxProfit(vector<int>& prices) {        if(prices.empty())		{			return 0;		}		//只有1个价格,无法交易		if(prices.size() <= 1)		{			return 0;		}		int size = prices.size();		int K = 2;		vector< vector<int> > dp( K + 1, vector<int>(size , 0) );		//dp[0][i] = 0		//dp[k][0] = 0,所以无需再初始化		//dp[k][i] = max( dp[k][i-1] , dp[k-1][j] + prices[i] - prices[j] ),j属于[0 , i-1]		//         = max ( dp[k][i-1], prices[i] + max(dp[k-1][j] - prices[j]),牛逼,把常量全部提取出来		//目标值dp[2][n-1]		int maxProf = 0;		for(int k = 1 ; k <= K ; k++)//这里限定k的结果,必须从1开始因为后面有k-1		{			int tempMax = dp.at(k-1).at(0) - prices.at(0);			for(int i = 1; i < size ; i++)//下标从1开始			{				dp.at(k).at(i) = max( dp.at(k).at(i-1) , prices.at(i) + tempMax );				//牛逼把常量拆分出来,最大值通过一次遍历即可,无需再次开一个循环				tempMax = max(tempMax , dp.at(k-1).at(i) - prices.at(i));				maxProf = max(maxProf, dp.at(k).at(i));			}		}		return maxProf;	}};void print(vector<int>& result){	if(result.empty())	{		cout << "no result" << endl;		return;	}	int size = result.size();	for(int i = 0 ; i < size ; i++)	{		cout << result.at(i) << " " ;	}	cout << endl;}void process(){	 vector<int> nums;	 int value;	 int num;	 Solution solution;	 vector<int> result;	 while(cin >> num )	 {		 nums.clear();		 for(int i = 0 ; i < num ; i++)		 {			 cin >> value;			 nums.push_back(value);		 }	 }}int main(int argc , char* argv[]){	process();	getchar();	return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表