int max_k =2;int[][][] dp = new int[n][max_k +1][2];for(int i =0; i < n; i++){for(int k = max_k; k >=1; k--){if(i -1==-1){/*处理 base case */}
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]);}}// 穷举了 n × max_k × 2 个状态,正确。return dp[n -1][max_k][0];
code
intmaxProfit(vector<int>& prices){int size = prices.size();int max_k =2;// i从1开始而不是0,这样可以使base case是 dp[0][0][0] 和 dp[0][0][1] 而不是 dp[-1][0][0] 或者 dp[-1][0]int dp[size +1][max_k +1][2];// 初始化for(int k = max_k; k >=0; k--){
dp[0][k][0]=0;
dp[0][k][1]= INT_MIN;}for(int i =1; i <= size; i++){
dp[i][0][0]=0;
dp[i][0][1]= INT_MIN;for(int k = max_k; k >=1; k--){
dp[i][k][0]= std::max(dp[i -1][k][0], dp[i -1][k][1]+ prices[i -1]);
dp[i][k][1]= std::max(dp[i -1][k][1], dp[i -1][k -1][0]- prices[i -1]);}}return dp[size][max_k][0];}
188. Best Time to Buy and Sell Stock IV
frame
有了上一题 k =2 的铺垫,这题应该和上一题的第一个解法没啥区别。但是出现了一个超内存的错误,原来是传入的 k 值会非常大,dp 数组太大了。现在想想,交易次数 k 最多有多大呢?
一次交易由买入和卖出构成,至少需要两天。所以说有效的限制 k 应该不超过 n/2,如果超过,就没有约束作用了,相当于 k =+infinity。这种情况是之前解决过的。
直接把之前的代码重用: