算法训练营day50_动态规划(3.23补)
123.买卖股票的最佳时机III
状态机dp;第i天有两个状态,持有或者不持有,故增加一维01,由于交易次数有限制,故增加一维交易次数;
状态表示:
f(i,j,0):前i天,不持有股票,完成j次完整交易(买入卖出)的最大利润;
f(i,j,1):前i天,持有股票,完成j次完整交易(买入卖出)的最大利润;
状态转移
初始化
状态机dp,初始状态为0,其余全为无穷;本题中,前i天,0次交易,不持有为0;
遍历
i,j都从1开始遍历,这里数组从0开始的,映射一下;
class Solution {
public:
int f[100010][3][2];
int maxProfit(vector<int>& prices) {
memset(f,-0x3f,sizeof f);
int n=prices.size();
for(int i=0;i<=n;i++) f[i][0][0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=2;j++){
f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]+prices[i-1]);
f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0]-prices[i-1]);
}
}
int ans=0;
for(int i=0;i<=2;i++){
ans=max(ans,f[n][i][0]);
}
return ans;
}
};
188.买卖股票的最佳时机IV
上题代码一起a了;模板题竟然难度也是困难;
class Solution {
public:
int f[1010][110][2];
int maxProfit(int k, vector<int>& prices) {
memset(f,-0x3f,sizeof f);
int n=prices.size();
for(int i=0;i<=n;i++) f[i][0][0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]+prices[i-1]);
f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0]-prices[i-1]);
}
}
int ans=0;
for(int i=0;i<=k;i++){
ans=max(ans,f[n][i][0]);
}
return ans;
}
};