leetcode算法-Best Time to Buy and Sell Stock IV
题目:给定一个数组prices[n],其中prices[i]代表第i天股票的价格,限定最多进行k次交易(买进和卖出股票算一次交易),在卖出之前必须进行买入操作,求股票交易的最大收益。
涉及算法:动态规划
主要思路:(主要是看了大佬的加上自己的理解)我们需要一个数组dp[k+1][prices.length]来记录利润数据。设定dp[i][j]代表第j天最多进行了i次交易的最大利润。在第j天怎么进行交易有三种情况,第一种,在第j天没有进行进行交易,那么第j-1天的最大利润就是第j天的最大利润,即dp[i][j] = dp[i][j-1];第二种,在第j天卖出股票,当然要保证能在第j天有股票可卖,那么一定有一天jj∈[0,j-1]是进行了买入股票操作,在第jj天买入股票之后的最大利润为dp[i-1][jj] - prices[jj],那么要保证第j天的例如最大,即要求一个jj使得dp[i-1][jj] - prices[jj]最大(这里就需要不断迭代);进行买入操作,但是进行买入操作肯定会使得当天利润减少,得到的不是最大利润,故不考虑第三种操作。
代码:
public int maxProfitIV(int k, int[] prices)
{
int len = prices.length;
if (k >= len / 2) return quickSolve(prices);//这里,因为k的值比较大,相当于不限定交易次数的买卖股票问题,就简单点计算,不然如果还按照原来的方法会超时
int[][] dp = new int[k+1][len];
for(int i=1;i<=k;i++)
{
//假定第一天买入
int tmpMax = -prices[0];
for(int j=1;j<len;j++)
{
dp[i][j] = Math.max(dp[i][j - 1], prices[j] + tmpMax);
//记录的始终是一次交易完成后的,买入后利润的最大值
//迭代求max(dp[i-1][jj] - prices[jj])值
tmpMax = Math.max(tmpMax, dp[i - 1][j - 1] - prices[j]);
}
}
return dp[k][len-1];
}
private int quickSolve(int[] prices) {
int len = prices.length, profit = 0;
for (int i = 1; i < len; i++)
// as long as there is a price gap, we gain a profit.
if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1];
return profit;
}