看上去是个背包
无脑码,样例都过不了
其实他过不了的原因是你先放了一个 很小的物品
又放了一个超过 s/2 的大物品,这样你每次放入背包时,他的转移都是合法的
但是如果你把小的拿掉,显然这个小的物品就是不合法的了
所以要从大到小考虑物品
这样只用在转移的时候保证体积从 s/2 + w[i] to w[i] 枚举就好了
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cstdio>
using namespace std;
const int MAXN = 305, MAXSIZ = 100005;
int n, tot;
int siz[MAXN];
bool f[MAXSIZ];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &siz[i]);
tot += siz[i];
}
f[0] = true;
sort(siz + 1, siz + n + 1);
for (int i = n; i >= 1; --i) {
for (int j = min(tot, tot / 2 + siz[i]); j >= siz[i]; --j) {
f[j] |= f[j - siz[i]];
}
}
int mini = (tot >> 1);
for (int i = tot; i >= mini; --i) if (f[i]) {
printf("%d
", i);
return 0;
}
puts("0");
return 0;
}