123.买卖股票的最佳时机III
链接:代码随想录
这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。
直接看答案,五种状态,清晰明白。
状态转移方程比较好想,初始值并不太好想。
具体来说:
基本明白思路后能一次写出
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<int>& prices) { int n=prices.size(); vector<vector<int>>dp(n,vector<int>(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<n;i++) { 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]); } return dp[n-1][4]; } };
188.买卖股票的最佳时机IV
看了题解,然后自己写出来了,一遍过啦啦啦啦啦
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<int>& prices) { int n=prices.size(); if(n==0) { return 0; } vector<vector<int>>dp(n,vector<int>(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<n;i++) { for(int j=1;j<2*k+1;j++) { if(j%2==1)//奇数 { dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]-prices[i]); } else { dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+prices[i]); } } } return dp[n-1][2*k]; } };