leetcode股票问题dp汇总

股票问题dp

1状态设定

定义dp[i][k][j]为第i天(从0~n-1),当前最多买入k次,j为0或1,表示当前是否持有股票。

2 递推关系
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
              max(   选择 rest  ,           选择 sell      )

解释:今天我没有持有股票,有两种可能:
要么是我昨天就没有持有,然后今天选择 rest,所以我今天还是没有持有;
要么是我昨天持有股票,但是今天我 sell 了,所以我今天没有持有股票了。

dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
              max(   选择 rest  ,           选择 buy         )

解释:今天我持有着股票,有两种可能:
要么我昨天就持有着股票,然后今天选择 rest,所以我今天还持有着股票;
要么我昨天本没有持有,但今天我选择 buy,所以今天我就持有股票了。

作者:labuladong
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/solution/yi-ge-tong-yong-fang-fa-tuan-mie-6-dao-gu-piao-wen/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
3 k的遍历顺序

如果k的定义是,当前最多买入k次,那么就从1~kmax;
如果k的定义是,当前还可以最多买k次,那么就从kmax~1;

4 basecase如何设计

当i==-1时,很容易有
dp[-1][任意的k][0]=0;//不论什么时候,当前还没开始,即使最多买k次,那么没有持有,最大利润就是0;
dp[-1][任意的k][1]=-inf;//不论什么时候,当前还没开始,最多买k次,当前已经持有,这是不可能的,因此定义为负无穷。

我们根据basecase,要设定的是i == 0的情况,所以我们必须对i==0的情况,带入到2里面去,最终得到如下代码!

代码

class Solution {
public:
    const int MinInf=INT_MIN;
    int maxProfit(vector<int>& prices) {
        int kmax=2;
        int n=prices.size();
        if(n==0)return 0;
        vector<vector<vector<int>>> dp(n,vector<vector<int>>(kmax+1,vector<int>(2,0)));
        for(int i=0;i<n;i++){
            for(int k=1;k<=kmax;k++){
                if(i==0){
                    dp[i][k][0]=0;
                    dp[i][k][1]=-prices[i];
                    continue;
                }
                dp[i][k][0]=max(dp[i-1][k][0],dp[i-1][k][1]+prices[i]);
                dp[i][k][1]=max(dp[i-1][k][1],dp[i-1][k-1][0]-prices[i]);
            }
        }
        return dp[n-1][kmax][0];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值