代码随想录|day50|动态规划part11● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III

链接:代码随想录

这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。

代码随想录|day50|动态规划part11● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV_第1张图片

 代码随想录|day50|动态规划part11● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV_第2张图片

 直接看答案,五种状态,清晰明白。

代码随想录|day50|动态规划part11● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV_第3张图片

 状态转移方程比较好想,初始值并不太好想。

具体来说:

基本明白思路后能一次写出 

class Solution {
    /*
    dp[i][0] 不操作
    dp[i][1]  第一次持有股票
    dp[i][2]  第一次不持有股票
    dp[i][3]  第二次持有股票
    dp[i][4]  第二次不持有股票


递推公式:
    dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
    dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i]);
    dp[i][3]=max(dp[i-1][3],dp[i-1][2]-prices[i]);
    dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[i]);

初始值:------------------啊啊啊啊好难想
   当i=0时,
    dp[0][0]------------------不操作,等于0
    dp[0][1]------------------第一次持有股票,等于 -prices[0]
    dp[0][2]-------------------0
    dp[0][3]                   -prices[i]或者0
    dp[0][4]                   prices[i]或者0
  
    */
public:
    int maxProfit(vector& prices) {
        int n=prices.size();
        vector>dp(n,vector(5,0));
        //初始化
        dp[0][0]=0;
        dp[0][1]=-prices[0];
        dp[0][2]=0;
        dp[0][3]=-prices[0];
        dp[0][4]=0;

        for(int i=1;i

188.买卖股票的最佳时机IV

本题是123.买卖股票的最佳时机III 的进阶版

链接:代码随想录

代码随想录|day50|动态规划part11● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV_第4张图片

代码随想录|day50|动态规划part11● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV_第5张图片

 

 看了题解,然后自己写出来了,一遍过啦啦啦啦啦

class Solution {
/*
呜呜呜好不容易送走了k=2次的,知道至少有2^2+1状态,
如若是k,难道要写2^k+1种状态吗?如果这么写,边界值k=100,2^100显然空间过于大了

这里想错了,j的范围就定义为 2 * k + 1。是线性的,因为对于第k次,有两个状态持有或者不持有。且奇数情况下固定初始值为-nums[0],偶数情况下固定初始值为0
即
dp[i][0] 不操作,初始值为0
dp[i][1]----第1次持有股票,初始值 -nums[0]
dp[i][2]----第1次不持有股票,初始值 0
dp[i][3]----第2次持有股票,初始值 -nums[0]
dp[i][4]----第2次不持有股票,初始值 0
.
.
.
dp[i][k]----第k次持有股票,初始值 -nums[0]
dp[i][2*k]----第2k次不持有股票,初始值 0



-----------------状态转移方程-------------------
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i])
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i])

*/
public:
    int maxProfit(int k, vector& prices) {
        int n=prices.size();
        if(n==0)
        {
            return 0;
        }
        vector>dp(n,vector(2*k+1,0));
        
        //初始化i=0,即状态转移矩阵的第一行
        for(int j=0;j<2*k+1;j++)
        {
            if(j%2==1)//奇数,初始化
            {
              dp[0][j]=-prices[0];
            }
            else
            {
              dp[0][j]=0;
            }
        }
        //同时也默认初始化j=0第一列所有都等于0了
        //状态转移啦,因为第一行已经初始化过了,所以从第二行开始
        for(int i=1;i

你可能感兴趣的:(动态规划,算法)