1.股票买卖问题
(1)交易次数k为1
买入和卖出各算一次操作
class Solution {
public int maxProfit(int[] prices) {
int n=prices.length;
int[][] dp=new int[n][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i<n;i++){
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
}
return dp[n-1][0];
}
}
(2)交易次数k无限制
class Solution {
public int maxProfit(int[] prices) {
int n=prices.length;
int[][] dp=new int[n][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i<n;i++){
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[n-1][0];
}
}
(3)交易次数限为2
2笔交易(买入和卖出两个操作算1笔交易)
class Solution {
public int maxProfit(int[] prices) {
int n=prices.length;
int k=2;
int[][][] dp=new int[n][k+1][2];
dp[0][0][0]=0;
for(int i=0;i<n;i++){
dp[i][0][0]=0;
dp[i][0][1]=-prices[i];
}
for(int j=0;j<=k;j++){
dp[0][j][0]=0;
dp[0][j][1]=-prices[0];
}
for(int i=1;i<n;i++){
for(int j=1;j<=k;j++){
dp[i][j][0]=Math.max(dp[i-1][j][0],dp[i-1][j][1]+prices[i]);
dp[i][j][1]=Math.max(dp[i-1][j][1],dp[i-1][j-1][0]-prices[i]);
}
}
return dp[n-1][k][0];
}
}
(4)交易次数限为k
k笔交易
class Solution {
public int maxProfit(int k, int[] prices) {
int n=prices.length;
if(n==0) return 0;
int[][][] dp=new int[n][k+1][2];
for(int i=0;i<n;i++){
dp[i][0][0]=0;
dp[i][0][1]=-prices[i];
}
for(int j=0;j<=k;j++){
dp[0][j][0]=0;
dp[0][j][1]=-prices[0];
}
for(int i=1;i<n;i++){
for(int j=1;j<=k;j++){
dp[i][j][0]=Math.max(dp[i-1][j][0],dp[i-1][j][1]+prices[i]);
//自身这种(0:不持有,1:持有)的设定已经符合了题的要求:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
dp[i][j][1]=Math.max(dp[i-1][j][1],dp[i-1][j-1][0]-prices[i]);
}
}
return dp[n-1][k][0];
}
}
(5)交易次数k无限制+冷冻期
class Solution {
public int maxProfit(int[] prices) {
int n=prices.length;
if(n<=1) return 0;//
int[][] dp=new int[n][2];
//base case
dp[0][0]=0;
dp[0][1]=-prices[0];
dp[1][0]=Math.max(dp[0][0],dp[0][1]+prices[1]);
dp[1][1]=Math.max(dp[0][1],-prices[1]);
//迭代
for(int i=2;i<n;i++){
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][1],dp[i-2][0]-prices[i]);
}
return dp[n-1][0];
}
}
(6)交易次数k无限制+手续费
class Solution {
public int maxProfit(int[] prices, int fee) {
int n=prices.length;
int[][] dp=new int[n][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i<n;i++){
//减去fee只能放在卖出的时候,写在买入那结果不对,可能因为到卖出才算一次完整操作,才需要减去手续费
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[n-1][0];
}
}