UVA323 Jury Compromise
UVA323 Jury Compromise - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
由于选择人数有限制(等于 \(m\)),因此考虑将人数设入动态规划的一维。
考虑目标是 \(D + P\) 最大,那么考虑背包,将 \(D + P\) 考虑成物品的总价值。
设 \(f(i, j, k)\),表示前 \(i\) 个人中选了 \(j\) 个人,\(D - P = k\),\(D + P\) 的最大值。
转移:\(f(i, j, k) = \max(f(i - 1, j, k), f(i - 1, j - 1, k - d[i] + p[i]) + d[i] + p[i])\)。
采用类似思想滚动第一维,由于是个 01 背包,可以彻底滚动掉。访问 \(f(j - 1, k - d[i] + p[i])\) 必须还处在 \(i - 1\) 这个阶段,所以 \(j\) 应倒序枚举。
不过,记录路径的数组不可以压缩维度!
/*
* @Author: crab-in-the-northeast
* @Date: 2022-11-12 04:14:51
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2022-11-12 05:24:51
*/
#include <bits/stdc++.h>
inline int read() {
int x = 0;
bool f = true;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
if (ch == '-')
f = false;
for (; isdigit(ch); ch = getchar())
x = (x << 1) + (x << 3) + ch - '0';
return f ? x : (~(x - 1));
}
inline bool gmx(int &a, int b) {
return b > a ? a = b, true : false;
}
const int maxn = 205;
const int maxm = 25;
const int maxv = (maxm * 20) << 1;
const int par = maxm * 20;
int f[maxm][maxv];
int d[maxn], p[maxn];
int pre[maxn][maxm][maxv];
void pr(int i, int j, int k) {
if (j == 0)
return ;
int id = pre[i][j][k + par];
pr(id - 1, j - 1, k - d[id] + p[id]);
printf(" %d", id);
}
int main() {
for (int cas = 1, n = read(), m = read(); n; ++cas, n = read(), m = read()) {
std :: memset(f, 0xc0, sizeof(f));
f[0][par] = 0;
for (int i = 1; i <= n; ++i) {
p[i] = read();
d[i] = read();
}
for (int i = 1; i <= n; ++i) {
for (int j = m; j; --j)
for (int k = -400; k <= 400; ++k)
if (gmx(f[j][k + par],
f[j - 1][k - d[i] + p[i] + par]
+ d[i] + p[i]))
pre[i][j][k + par] = i;
else
pre[i][j][k + par] = pre[i - 1][j][k + par];
}
for (int dif = 0; dif <= 400; ++dif) {
int ps = f[m][par + dif], ng = f[m][par - dif];
if (ps < 0 && ng < 0)
continue;
int k = dif;
if (ps < 0 || ng > ps)
k = -dif;
printf("Jury #%d\n", cas);
printf("Best jury has value %d for prosecution and value %d for defence:\n", (f[m][k + par] - k) >> 1, (f[m][k + par] + k) >> 1);
pr(n, m, k);
puts("");
puts("");
break;
}
}
return 0;
}