题目
假设有一个数组,其对i个元素是一支给定的股票在某一天i的价格。
设计一个算法,来找到最大的赢利点。你最多可以进行两次交易。
注意:你不能同时进行多次交易(例如,在再次购买之前,必须先销售该股票)。
解析
当题目把交易次数限定为两次,这道题就成为一道动态规划的问题。根据任意一个数组的下标i,可以将数组分为两个部分:A[0,i] 和 A[i+1,n],那么两个数组分别产生两个利润MaxProfit(0,i) 和 MaxProfit(i+1,n),所以对于最大利润,我们可以用如下表达式来表述:
FinalMaxProfit = max( MaxProfit(0,i) + MaxProfit(i+1,n) ) , 0<= i <n
这样题目就变简单了,计算好MaxProfit(0,i) 和 MaxProfit(i+1,n)。然后将数组再扫描一遍,就可以轻松地计算出FinalMaxProfit。
代码
int maxProfit(vector<int>&prices){
if(prices.size() <= 1) return 0;
vector<int> maxFromLeft(prices.size(), 0);
vector<int> maxFromRight(prices.size(), 0);
int minV = INT_MAX, maxP = INT_MIN;
for(int i=0; i<prices.size(); i++)
{
if(minV > prices[i]) minV = prices[i];
int temp = prices[i] - minV;
if(temp > maxP)
maxP = temp;
maxFromLeft[i] = maxP;
}
int maxV = INT_MIN;
maxP = INT_MIN;
for(int i=prices.size()-1; i>=0; i--)
{
if(maxV < prices[i]) maxV = prices[i];
int temp = maxV - prices[i];
if(temp > maxP)
maxP = temp;
maxFromRight[i] = maxP;
}
for(int i=0; i<prices.size()-1; i++)
{
int sum = maxFromLeft[i] + maxFromRight[i+1];
if(sum > maxProfit) maxProfit = sum;
}
if(maxProfit < maxFromRight[0])
maxProfit = maxFromRight[0];
return maxProfit;
}