题目大意
这道题与III的区别在于给定交易数量为k,然后求最大利润。
分析
将III的程序维度稍微修改一下,即可完成本题,但是如果直接提交的话,会由于k达到十亿爆出内存溢出,我本来以为要用什么奇妙的滚动数组来优化,屡次尝试未果后参考了别人的题解,发现一次交易至少需要两天,那么我们可以认为如果k > n / 2,就能通过无限次的交易那种方案来解决,即利用LeetCode 122那道题的方法分类讨论一下,避免了k特别大的情况。
源代码
public int maxProfit(int[] prices) {
int n = prices.length;
int sum = 0, minm = prices[0], maxm = prices[0];
for(int i = 1; i < n; i++) {
if(prices[i] > maxm) {
maxm = prices[i];
sum += (maxm - minm);
minm = prices[i];
maxm = prices[i];
} else {
if(prices[i] < minm) {
minm = prices[i];
maxm = prices[i];
}
}
}
return sum;
}
public int maxProfit(int k, int[] prices) {
if(prices.length <= 1) {
return 0;
}
if(k > prices.length / 2) {
return maxProfit(prices);
}
int dp[][][] = new int[2][k + 1][2];
for(int i = 1; i <= k; i++) {
dp[0][i][1] = -prices[0];
}
for(int i = 1; i < prices.length; i++) {
for(int j = 1; j <= k; j++) {
dp[1][j][0] = Math.max(dp[0][j][0], dp[0][j][1] + prices[i]);
dp[1][j][1] = Math.max(dp[0][j][1], dp[0][j - 1][0] - prices[i]);
}
for(int j = 1; j <= k; j++) {
dp[0][j][0] = dp[1][j][0];
dp[0][j][1] = dp[1][j][1];
}
}
return dp[1][k][0];
}