题目分析:
- 用一个数组表示股票每天的价格,数组中第i个数表示股票在第i天的价格。最多可以交易k次,但手上只能持有一支股票,求此时的最大收益。
解题思路:
动态规划求解
1)如果交易次数大于股票变化的天数,次数利用贪心法求解最大收益即可。
2)如果不满足1),则从所有的价格变化序列中,挑选出2*k个元素,组成交易,交易过程为交替进行。此时利用动态规划进行求解。利用两个数组分别记录:当前到达第i天最多可以进行j次交易所得到的最大利润global[i][j]和当前到达第i天最多可以进行j次交易,而且最后一次交易在当天卖出所得到的最大利润。对应的转移方程为:
global[i][j] = max(local[i][j], global[i-1][j])
local[i][j] = max(global[i-1][j-1] + max(diff,0), local[i-1][j] + diff)。
实现程序
class Solution { public: int maxProfit(int k, vector<int> &prices) { // 如果交易次数大于股票价格变化的天数,此时贪心法,求最大收益即可。 if (k >= prices.size()) { return maxProfit2(prices); } // 记录到达第i天最多可以进行j次交易,所得到的最大利润 vector<int> max_local(k + 1, 0); // 记录到达第i天最可以进行j次交易,而且最后一次交易在当天卖出,所得到的最大利润 vector<int> max_global(k + 1, 0); int diff; for (int i = 0; i < prices.size() - 1; i++) { // 第i天进行交易的利润 diff = prices[i + 1] - prices[i]; for (int j = k; j >= 1; j--) { max_local[j] = max(max_global[j - 1] + max(diff, 0), max_local[j] + diff); max_global[j] = max(max_local[j], max_global[j]); } } return max_global[k]; } int maxProfit2(vector<int> &prices) { if (prices.size() < 2) return 0; int profit = 0; for (int i = 0; i < prices.size() - 1; i++) //注意(int)prices.size() - 1与prices.size() - 1结果值不同 { if (prices[i + 1] > prices[i]) profit += prices[i + 1] - prices[i]; } return profit; } };
参考文献:http://blog.csdn.net/foreverling/article/details/43911309