//f[i,j,1]表示走到第i天已经进行完j次交易并且手中没有股票的所有的购买方式的集合 //f[i,j,0]表示走到第i天并且正在进行第j次交易且手中有货的所有的购买方式的集合 //属性利益最大值 //f[i,j,0]=max(f[i-1,j,0],f[i-1,j,1]+w[i]) //表示从手中无货(不买)转移到手中无货 或者 手中有货(卖出)转移到手中无货 //f[i,j,1]=max(f[i-1,j,1],f[i-1,j-1,0]-w[i]) //表示从手中有货(不卖) 转移到手中有货 或者 手中无货(买进) 转移到手中有货 #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 100010, M = 110, INF = 0x3f3f3f3f; int n, m; int w[N]; int f[N][M][2]; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]); //一开始手中一定无货 也就是从初始状态走到无货状态 那么到有货状态为负无穷 memset(f, -0x3f, sizeof f); //如果一次交易都没有进行,j=0,表示手中无货 f[i,0,0]是合法的,为0 //f[i,0,1]不合法,为负无穷 for (int i = 0; i <= n; i ++ ) f[i][0][0] = 0; for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) { f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + w[i]); f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j - 1][0] - w[i]); } int res = 0; for (int i = 0; i <= m; i ++ ) res = max(res, f[n][i][0]); printf("%d ", res); return 0; }