虽然知道有更加简便的做法,但还是要问为什么以下做法的正确性不成立:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e3 + 10;
ll n, m, p[N][N];
ll a[N], dp[N][N];
int main () {
cin >> n >> m;
for (int i = 1; i <= n; ++ i) {
cin >> a[i];
}
memset (p, 0, sizeof p);
for (int i = 1; i <= n; ++ i) {
for (int j = m; j >= 0; -- j) {
if (j >= 1) {
if (dp[i - 1][j] >= dp[i - 1][j - 1] + a[i] * (p[i - 1][j - 1] + 1)) {
dp[i][j] = dp[i - 1][j];
p[i][j] = p[i - 1][j];
}
else {
p[i][j] = p[i - 1][j - 1] + 1;
dp[i][j] = max (dp[i - 1][j], dp[i - 1][j - 1] + a[i] * p[i][j]);
}
}
else {
dp[i][j] = dp[i - 1][j];
p[i][j] = p[i - 1][j];
}
}
}
cout << dp[n][m];
return 0;
}
p 数组为记录当前状态下选了多少个,用来解决原序列和子序列下标不对应的问题。