一、题目
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [2,4,1], k = 2
输出: 2
解释: 在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
示例 2:
输入: [3,2,6,5,0,3], k = 2
输出: 7
解释: 在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。
二、 解决
系列:【LeetCode】121. 买卖股票的最佳时机、【LeetCode】122. 买卖股票的最佳时机 II、【LeetCode】123. 买卖股票的最佳时机 III
1、递归
思路:
1、状态定义:
M[day][cnt][status]含义: day: 表示天,取值0~n-1;
cnt: 交易几次,取值0~k次;
status: 交易状态,表示是否拥有股票。 0-没有股票,只能买;1-拥有1股,只能卖。
2、状态方程
for day : 0-->n-1
for cnt : 0-->k
MP[day,cnt,0]:表示当天没有股票;
MP[day,cnt,1]:表示当天拥有一股。
// 核心部分--状态方程
MP[day,cnt,0] = max {
MP[day-1, cnt, 0] // 不动
MP[day-1, cnt-1, 1]+a[day] // 卖掉一股
}
MP[day,cnt,1] = max {
MP[day-1,cnt,1] // 不动
MP[day-1,cnt-1,0]-a[day] // 买入一股
}
return MP[n-1, {
0,...,k}, 0]:第n天且没有股票的时候,之前交易的最大值
代码:
class Solution {
public int maxProfit(int k, int[] prices) {
if(prices==null || prices.length==0) {
return 0;
}
return dfs(0, 0, 0, k, prices);
}
// 计算k次交易,index表示当前是哪天,status是买卖状态,coutnt为交易次数
private int dfs(int index, int status, int count, int k, int[] prices) {
if(index==prices.length || count==k) {
return 0;
}
int a=0,b=0,c=0;
// 保持不动
a = dfs(index+1, status, count, k, prices);
if(status==1) {
// 卖一股,并将交易次数+1
b = dfs(index+1, 0, count+1, k, prices)+prices[index];
} else {
// 买一股
c = dfs(index+1, 1, count, k, prices)-prices[index];
}
return Math.max(Math.max