动态规划解题步骤
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
121. 买卖股票的最佳时机
这道题虽然自己做出来了,但是做了后面的题再回头看它就有了不一样的理解。curMin更重要的代表了一种状态,代表遍历到当前时间时最低的股价。本质上curMin也应该是一个和prices等长的数组,表示了每天的状态(这就是这道题动态规划思路体现的位置),只是由于每天的状态都由前一天完全确定,且我们最终也只需要最后一天的结果,所以空间上可以优化成O(1)
。
class Solution {
public int maxProfit(int[] prices) {
int curMin = prices[0];
int max = 0;
for(int i = 0; i < prices.length; i++){
int profit = prices[i] - curMin;
max = Math.max(max, profit);
curMin = Math.min(curMin, prices[i]);
}
return max;
}
}
122. 买卖股票的最佳时机 II
这道题给了我一种贪心的感觉,收获每个正收益即可。
class Solution {
public int maxProfit(int[] prices) {
int max = 0;
for(int i = 1; i < prices.length; i++)
max += Math.max(0, prices[i] - prices[i-1]);
return max;
}
}
动态规划的版本代码先放在这里,看了下一道题再看就非常易懂了。
class Solution { //动态规划版本
public int maxProfit(int[] prices) {
int[] stat = new int[2];
stat[0] = Integer.MIN_VALUE;
for(int i = 0; i < prices.length; i++){
stat[0] = Math.max(stat[0], stat[1] - prices[i]);
stat[1] = Math.max(stat[1], stat[0] + prices[i]);
}
return stat[1];
}
}
123. 买卖股票的最佳时机 III
这道题和188. 买卖股票的最佳时机 IV可以说一模一样,就按照k次买入卖出来做,对于本题取k=2即可。
最主要的就是要描述每天的状态,每天可以有多少种状态呢?对于最多k次交易,我们可以想到有第1次买入,第1次卖出 ... 第k次买入,第k次卖出共有2*k次状态。因此dp数组形状应该是k * n
,确定了dp数组就去考虑如何更新dp数组就好了。
这里更详细解释下dp[i][j]
的含义:第j
天状态为i
时的最大利润,一定仔细仔细理解这句话。
注意看下面这个表格中所有的状态:第一次买入代表当前还持有第一次买入的股票,可以是当天买的,也可以是之前买入的。其他状态的理解也是这样。
day1 | 2 | ... | day n | |
---|---|---|---|---|
第一次买入 | ||||
第一次卖出 | ||||
... | ||||
第k次买入 | ||||
第k次卖出 |
// 188
class Solution {
public int maxProfit(int k, int[] prices) {
int[] states = new int[2*k];
Arrays.fill(states, Integer.MIN_VALUE);
for(int i = 0; i < prices.length; i++){
for(int j = 0; j < k; j++){
states[2*j] = Math.max(states[2*j],
2*j == 0 ? -prices[i] : states[2*j-1] - prices[i]);
states[2*j+1] = Math.max(states[2*j+1],
states[2*j] + prices[i]);
}
}
return states[2*k-1];
}
}
class Solution {
public int maxProfit(int[] prices) {
int[] stat = new int[4];
Arrays.fill(stat, Integer.MIN_VALUE);
for(int i = 0; i < prices.length; i++){
stat[0] = Math.max(stat[0], -1 * prices[i]);
stat[1] = Math.max(stat[1], prices[i] + stat[0]);
stat[2] = Math.max(stat[2], stat[1] - prices[i]);
stat[3] = Math.max(stat[3], prices[i] + stat[2]);
}
return stat[3];
}
}
标签:Part09,stat,int,max,41,states,prices,Day,Math
From: https://www.cnblogs.com/12sleep/p/18355921