Leetcode 188. Best Time to Buy and Sell Stock IV

Problem:

 

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 k transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

Example 1:

Input: [2,4,1], k = 2
Output: 2
Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.

Example 2:

Input: [3,2,6,5,0,3], k = 2
Output: 7
Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.
             Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.

 

Solution:

  终于来到了这道赫赫有名的动态规划问题。首先如果k大于数组长度,则可以轻松的用动态规划解决,在此不加赘述。我们要解决的是k小于数组长度的情况下,如何使用动态规划。这道题之所以难是因为它是有两种状态的互相转移。此题和Leetcode 801有相似之处。对于某一天的交易,可能有两种情况,即卖出手中持有的股票或继续持有。这里维护两个数组local和global。local[i][j]表示最后一次买卖在第i天卖出,同时交易次数小于等于j次的最大收益,global[i][j]表示前i天完成小于等于j次交易的最大收益。因此global[i][j]就很容易得到global[i][j] = max(global[i-1][j],local[i][j]),即i-1天进行j次交易的最大收益和第i天卖出股票的收益的最大值。难点在于local[i][j]的计算,local[i][j]可以分为两部分,对于第一部分global[i-1][j-1] + max(diff,0),可以理解为前一天进行j-1次交易的收益加上从昨天到今天的收益,如果收益为负数,则理解为当天买当天卖,不赚也不赔但交易次数加1,如果赚钱则更好。第二部分local[i-1][j] + diff可以理解为前一天卖出股票的收益加上今天和昨天的收益差,那么为什么不是local[i-1][j-1]+diff呢,因为这里相当与第i-1天卖出的交易变为第i天卖出,所以交易次数不变。

Code:

 

 1 class Solution {
 2 public:
 3     int maxProfit(int k, vector<int>& prices) {
 4         int m = prices.size();
 5         if(k >= m){
 6             int result = 0;
 7             for(int i = 0;i < m-1;++i){
 8                 int dif = prices[i+1]-prices[i];
 9                 result += (dif>0 ? dif : 0);
10             }
11             return result;
12         }
13         vector<vector<int>> local(m,vector<int>(k+1));
14         vector<vector<int>> global(m,vector<int>(k+1));
15         for(int i = 1;i != m;++i){
16             int diff = prices[i] - prices[i-1];
17             for(int j = k;j >= 1;--j){
18                 local[i][j] = max((global[i-1][j-1] + max(diff,0)),local[i-1][j] + diff);
19                 global[i][j] = max(global[i-1][j],local[i][j]);
20             }
21         }
22         return global[m-1][k];
23     }
24 };

 

转载于:https://www.cnblogs.com/haoweizh/p/10185493.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值