You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

36 lines
1.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 110;
int n, k;
int w[N];
int f[N][M][2];
// 以卖出做为一次完整交易的分界线
// f[i][j][0/1]定义成 前i天 完成恰好是j次交易 且 决策为0/1的集合
int main() {
cin >> n >> k;
for (int i = 1; i <= n; ++i) cin >> w[i];
memset(f, -0x3f, sizeof f); // 其它状态目前是无效状态或者是未知状态
for (int i = 0; i <= n; i++) f[i][0][0] = 0; // 0次交易手中无股票最大收益是0
for (int i = 1; i <= n; i++) { // 枚举每一天
for (int j = 0; j <= k; j++) { // 枚举到这一天时恰好进行了j次交易
// ① 这个 if(j) 可以理解为先把后面的状态转移方程写出来再观察一下发现j>=1否则数组索引出负值
// ② 现实意义理解:如果 j=0时就是上面进行的初始值是固定值不需要转移
// ③ 手中无股票的状态,可以由前一天手中无股票的状态,和,前一天手中有股票但卖出了,两种状态转移而来
// ④ 最开始时,手中无股票,定义是原点,现在又到了手中无股票的状态,这是一个轮回,所以卖出是一个完整交易的临界点
if (j) f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j - 1][1] + w[i]);
// ⑤ 手中有股票,要么是昨天手中股票,继续持有,要么是昨天手中无股票,购入了
f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j][0] - w[i]);
}
}
int res = 0;
for (int i = 0; i <= k; i++) res = max(res, f[n][i][0]);
cout << res << endl;
return 0;
}