Reference resources: Portal
Define the general status dp[i][j][k] array, meaning dp [stock price on the first day... The nth day] [limit the number of transactions] [0 not held shares; 1 held shares]
General state transfer equation:
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] );
Initialization: adjust according to different topics
Best time to buy stock I (click the question to enter the original question)
There is no limit on the number of transactions
public int maxProfit(int[] prices) { int len = prices.length; if(len ==0 || len == 1) { return 0; } int[][] dp = new int[ len + 2 ][4]; //dp[i][j] refers to the number of times that the stock status is (1 holding stock, 0 no stock) as many as possible on day I for (int i = 0; i < len; i++) { if (i == 0) { dp[i][0] = 0; dp[i][1] = - prices[i]; continue; }else if(i == 1){ dp[1][0] = Math.max(dp[0][0],dp[0][1]+prices[i]); dp[1][1] = Math.max(dp[0][1], - prices[i]); continue; } 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[len-1][0]; }
The best time to buy and sell stocks includes handling fees (click the question to enter the original question)
public int maxProfit(int[] prices, int fee) { int len = prices.length; if(len ==0 ) { return 0; } int[][] dp = new int[ len + 2 ][4]; //dp[i][j] represents the maximum profit with the stock status of (1 holding stock, 0 no stock) on day I for (int i = 0; i < len; i++) { if (i == 0) { dp[i][0] = 0; dp[i][1] = - prices[i] ; continue; } 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[len-1][0]; }
Best time to buy and sell shares III (click the question to enter the original question)
public int maxProfit(int[] prices) { int len = prices.length; if(len == 0 ) { return 0; } int[][][] dp = new int[ len + 2 ][4][2]; // dp[i][j][k] refers to the maximum profit of j transactions (up to two transactions) of stocks on the I day and the status is K (0 no holding 1 holding) for (int i = 0; i < len; i++) { for (int j = 1; j <= 2; j++) { if(i == 0 && j == 1) { dp[i][j][0] = 0; dp[i][j][1] = -prices[i]; continue; }else if(i == 0 && j == 2) { dp[i][j][0] = 0; dp[i][j][1] = -999999; continue; } 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 Math.max(dp[len-1][1][0],dp[len-1][2][0]); }
Best time to buy and sell stocks IV (click the question to enter the original question)
When the following code is submitted at the beginning, an out of memory error is reported
public int maxProfit(int k, int[] prices) { int len = prices.length; if(len == 0 ) { return 0; } int[][][] dp = new int[ len + 2 ][k+2][2]; // dp[i][j] refers to the maximum profit of j transactions (up to two) of shares on the I day and the status is (0 no holding 1 holding) for (int i = 0; i < len; i++) { for (int j = 1; j <= k; j++) { if(i == 0 && j == 1) { dp[i][j][0] = 0; dp[i][j][1] = -prices[i]; continue; }else if(i == 0 && j == 2) { dp[i][j][0] = 0; dp[i][j][1] = -999999; continue; } else if(i == 0){ dp[i][j][0] = 0; dp[i][j][1] = -999999; continue; } 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] ); } } int max = 0; for(int i = 1;i <= k;i++){ max = Math.max(max,dp[len-1][i][0]); } return max; }
optimization
Scrolling array optimizes space into two dimensions
int[][] dp = new int[k+2][2]; // dp[i][j] represents the maximum profit of j transactions (up to two transactions) with the status of k (0 no holding 1 holding) for (int i = 0; i < len; i++) { for (int j = 1; j <= k; j++) { if(i == 0 && j == 1) { dp[j][0] = 0; dp[j][1] = -prices[i]; continue; }else if(i == 0 && j == 2) { dp[j][0] = 0; dp[j][1] = -999999; continue; } else if(i == 0){ dp[j][0] = 0; dp[j][1] = -999999; continue; } dp[j][0] = Math.max(dp[ j ][0], dp[ j ][1] + prices[i] ); dp[j][1] = Math.max(dp[ j ][1], dp[ j-1 ][0] - prices[i] ); } } int max = 0; for(int i = 1;i <= k;i++ ){ max = Math.max(dp[i][0],max); } return max;
The result is still out of memory...
It is found that k is related to the length of the prices [] array. Add the following judgment
int n = prices.length; if (k >= n / 2) { // In this case, the problem degenerates into a common stock trading problem int maxProfit = 0; for (int i = 1; i < n; i++) { if (prices[i] > prices[i - 1]) { maxProfit += prices[i] - prices[i - 1]; } } return maxProfit; }
614 original articles published, praised by 110 people, 400000 visitors+