🍑 OJ专栏
🍑 股票买卖 Ⅳ
输入
3 2
2 4 1
输出
2
输入
6 2
3 2 6 5 0 3
输出
7
🍑 状态机
🍤 f[k][i][j]:表示在前 i 支股票中考虑,完成了j次交易,且当前状态为 k(0为空仓,1为持仓)
🍤 j:买入就 +1,卖出不处理(买入卖出才算一次完整的交易)
import java.io.*;
import java.util.*;
public class Main
{
static int N = 100010, INF = 0x3f3f3f3f;
static int M = 110;
static int[][][] f = new int[2][N][M];
static int[] w = new int[N];
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException
{
Scanner sc = new Scanner(System.in);
String[] ss = in.readLine().split(" ");
int n = Integer.parseInt(ss[0]);
int k = Integer.parseInt(ss[1]);
ss = in.readLine().split(" ");
for (int i = 1; i <= n; i++)
w[i] = Integer.parseInt(ss[i - 1]);
//开始时:所有的持仓状态都是非法的(因为所有持仓状态都有可能影响后边的结果)
for (int i = 0; i <= n; i++)
for (int j = 0; j <= k; j++)
f[1][i][j] = Integer.MIN_VALUE / 2;
// DP
int res = 0;
for (int i = 1; i <= n; i++)// 枚举物品
{
for (int j = 1; j <= k; j++)// 枚举交易次数
{
//当前空仓 前一天空仓 前一天卖出(不算一次交易,只算完成交易)
f[0][i][j] = Math.max(f[0][i - 1][j], f[1][i - 1][j] + w[i]);
//当前持仓 前一天持仓 前一天买入
f[1][i][j] = Math.max(f[1][i - 1][j], f[0][i - 1][j - 1] - w[i]);
res = Math.max(res, f[0][n][j]);
}
}
System.out.println(res);
}
}
👨🏫 参考题解