hdu 1059
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1059
题意:有价值为1,2,……,6的大理石各若干个,求是否能平分给两个人。
mark:看别人说多重背包,一直不知道在说什么。后来终于懂了,把总价值平分,往背包里放东西,如果最后恰好等于总价值的一半,那么就可以放进去。
这个代码就当模版用了。。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> int a[7], vmax; int dp[120010]; int max(int a, int b) {return a > b ? a : b;} void zero(int cost, int weight) //01背包 { int i; for(i = vmax; i >= cost; i--) dp[i] = max(dp[i], dp[i-cost]+weight); } void com(int cost, int weight) //完全背包 { int i; for(i = cost; i <= vmax; i++) dp[i] = max(dp[i], dp[i-cost]+weight); } void mut(int cost, int weight, int amount) //多重背包 { int i; if(cost*amount >= vmax) com(cost, weight); else { for(i = 1; i <= amount; i *= 2) { zero(i*cost, i*weight); amount -= i; } zero(amount*cost, amount*weight); } } int main() { int i,j; j = 1; while(scanf("%d", &a[1])) { memset(dp, 0, sizeof(dp)); vmax = a[1]; for(i = 2; i < 7; i++) { scanf("%d", a+i); if(a[i] > 10) a[i] %= 10; vmax += i*a[i]; } if(!vmax) break; printf("Collection #%d:\n", j++); if(vmax%2) {puts("Can't be divided.\n"); continue;} vmax /= 2; for(i = 1; i < 7; i++) mut(i, i, a[i]); if(dp[vmax] == vmax) puts("Can be divided.\n"); else puts("Can't be divided.\n"); } return 0; }