题目:
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).
如果你只被允许完成最多两次交易,设计一个算法,找出最大的利润。但是,同一时间不能进行多次交易。
思路:
设状态f ( i ),表示区间[0 , i ](0 ≤ i ≤ n − 1) 的最大利润,状态 g ( i ),表示区间 [ i, n −1](0 ≤ i ≤ n − 1) 的最大利润,则最终答案为max {f (i ) + g (i )} , 0 ≤ i ≤ n − 1。
允许在一天内买进又卖出,相当于不交易,因为题目的规定是最多两次,而不是一定要两次。
求f ( i ) 可以参考:http://blog.csdn.net/u012243115/article/details/41170277 的第二种方法。
代码:
class Solution {
public:
///设状态 f ( i ),表示区间 [0 , i ](0 ≤ i ≤ n − 1) 的最大利润,从前向后遍历(表示i之前的数组的最大利润),用最大的-最小的
//状态 g ( i ),表示区间 [ i, n − 1](0 ≤ i ≤ n − 1) 的最大利润,从后向前遍历(表示i之后的数组的最大利润),也用最大的-最小的
//则最终答案为 max {f (i ) + g (i )} , 0 ≤ i ≤ n − 1。
//允许在一天内买进又卖出,相当于不交易,因为题目的规定是最多两次,而不是一定要两次。
//将 原 数 组 变 成 差 分 数 组, 本 题 也 可 以 看 做 是 最 大 m 子 段 和, m = 2
int maxProfit(vector<int> &prices)
{
int len = prices.size();
if(len < 2)
return 0;
vector<int> f(len , 0);
vector<int> g(len , 0);
int curMin = prices[0];//初始化最小值
for(int i = 1 ; i < len ; i++)
{
//找到当前最小的
if(prices[i] < curMin)
curMin = prices[i];
//求f[i],比较(当前值-最小的)和之前保存的最大的哪个大
f[i] = max(f[i-1] , prices[i] - curMin);
}
for(int j = len - 2 ; j >= 0 ; j-- )
{
if(curMax < prices[j])
curMax = prices[j];
g[j] = max(g[j+1],curMax - prices[j]);
}
int result = 0;
for(int k = 0 ; k < len ; k++)
{
if(result < (f[k] + g[k]))
result = f[k] + g[k];
}
return result;
}
};