题目大意:将一组物品分成两组,每个物品都可以不出现在任何一组。希望两组的重量差异不超过M,最大化总重量。
https://ac.nowcoder.com/acm/problem/19158
基本就是一个背包问题的变体,对于前i个物品,差异为gap时的最大总重量进行dp即可。
转移为(i, gap) -> (i + 1, gap)和(i, gap) -> (i + 1, gap + wt[i + 1])和(i, gap) -> (i + 1, abs(gap - wt[i + 1]))。注意,gap的中间值是可以超过M的,需要给一个比较大的界,比如w1+...+wn。
#define MAXN 105
#define MAXW 20000
#define INF 20000
int N, M;
int wt[MAXN];
int dp[MAXN][MAXW];
int doit() {
REP(i, N) {
int w = wt[i];
if (i == 0) {
REP(j, MAXW) {
dp[i][j] = -INF;
}
dp[i][0] = 0;
dp[i][w] = w;
continue;
}
REP(j, MAXW) {
dp[i][j] = dp[i - 1][j];
}
REP(j, MAXW) {
VI trans = {j + w, abs(j - w)};
for (int t : trans) {
if (0 <= t && t < MAXW) {
dp[i][t] = max(dp[i][t], dp[i - 1][j] + w);
}
}
}
}
int ans = 0;
REP(j, M + 1) {
ans = max(ans, dp[N - 1][j]);
}
return ans;
}
int main(int argc, char* argv[]) {
read(N);read(M);
read(wt, N);
printint(doit());
return 0;
} 
京公网安备 11010502036488号