https://www.nowcoder.com/discuss/93316
动态规划
#include <bits/stdc++.h>
// https://www.nowcoder.com/question/next?pid=8537290&qid=141068&tid=17473994
using namespace std;
#define M(a, b) memset(a,b,sizeof(a))
// memset(a,0x3f,sizeof(a))
//memset(a,0xcf,sizeof(a))
typedef long long LL;
int myswap(int &x, int &y) {
int a = x;
x = y;
y = a;
}
int main() {
int n;
cin >> n;
vector<int> x(n + 1), y(n + 1);
for (int i = 1; i <= n; i++) {
cin >> x[i] >> y[i];
}
int sumx = accumulate(x.begin(), x.end(), 0);
int sumy = accumulate(y.begin(), y.end(), 0);
int INF = -sumy * 4;
// 滚动数组, f[i][j] 定义取前i张卡片,A和B两人的差值为j时的团队最大分数值
// 因为差值可能为负数,而数组下标不能为负数,所以加上 sumx 变为大于等于0的数,注意只需要在第33行第一轮加上sumx 即可,初始化为 INF
vector<vector<int>> f(2, vector<int>(2 * sumx + 2, INF));
int pre = 0, cur = 1;
f[cur][sumx] = 0;
int total = 2 * sumx + 2;
for (int i = 1; i <= n; i++) {
myswap(pre, cur);
for (int j = 1; j <= 2 * sumx + 1; j++) {
f[cur][j] = f[pre][j]; // 初始化,当前状态等于前一状态的值
}
for (int j = 1; j <= 2 * sumx + 1; j++) {
if (j + x[i] < total) {
// j = j+x[i] (上一个状态的差值) - x[i] 当前状态的差值
f[cur][j] = max(f[cur][j], f[pre][j + x[i]] + y[i]);
printf("f[pre][j + x[i]] %d f[cur][j] %d \n", f[pre][j + x[i]], f[cur][j]);
}
if (j - x[i] >= 1) {
// j = j-x[i] (上一个状态的差值) + x[i] 当前状态的差值
// printf("f[pre][j + x[i]] %d \n", f[pre][j - x[i]]);
f[cur][j] = max(f[cur][j], f[pre][j - x[i]] + y[i]);
printf("f[pre][j + x[i]] %d f[cur][j] %d \n", f[pre][j + x[i]], f[cur][j]);
}
}
}
int ans = f[cur][sumx];
cout << ans << endl;
// cout<<f[cur][0]<<endl;
return 0;
}