HDU-1171 Big Event in HDU 背包
通过给定的数据组成可及的状态。最后再中中间开始遍历所有可及的状态。就是一个完全背包,用二进制优化。
代码如下:
#include <cstdlib> #include <cstdio> #include <cstring> #define MAXN 250005 using namespace std; int N, dp[MAXN], p[55], n[55], total; void zobag(int x) { for (int i = total>>1; i >= x; --i) { if (dp[i-x]) { dp[i] = 1; } } } void DP() { for (int i = 0; i < N; ++i) { int k = 1; while (k <= n[i]) { zobag(p[i]*k); k <<= 1; } zobag(p[i]*(n[i]-(k>>1))); } } int main() { while (scanf("%d", &N), N >= 0) { total = 0; memset(dp, 0, sizeof (dp)); dp[0] = 1; for (int i = 0; i < N; ++i) { scanf("%d %d", &p[i], &n[i]); total += p[i]*n[i]; } DP(); for (int i = total>>1; i >= 0; --i) { if (dp[i]) { printf("%d %d\n", total-i, i); break; } } } return 0; }