题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059
第i种物品的价值就是i 然后只输入每种物品的个数。。
多case中一定一定要memset
思路:如果总价值是奇数直接不可能,偶数的话然后将总价值分一半为背包容量,再进行多重背包,最后dp[v]==v 就是可以分。。
还有就是格式一开始有点问题。。题目说的是每组后都要空行。。
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int dp[120010]; int m[10]; int main() { int kase = 0; while(1) { memset(dp,0,sizeof(dp)); int sum = 0; for(int i = 1;i <= 6;i++) { cin >> m[i]; sum += m[i]*i; } if(!m[1]&&!m[2]&&!m[3]&&!m[4]&&!m[5]&&!m[6]) break; int v = sum/2; if(sum%2 != 0) { //if(kase != 0) printf("\n"); printf("Collection #%d:\nCan't be divided.\n\n",++kase); } else { int v = sum/2; for(int i = 1;i <= 6;i++) { if(i*m[i] > v) { for(int j = i;j <= v;j++) dp[j] = max(dp[j],dp[j-i]+i); } else { int k = 1; while(k < m[i]) { for(int j = v;j >= k*i;j--) dp[j] = max(dp[j],dp[j-k*i]+k*i); m[i] -= k; k *= 2; } for(int j = v;j >= m[i]*i;j--) dp[j] = max(dp[j],dp[j-m[i]*i]+m[i]*i); } } //cout << dp[v] << endl; //if(kase != 0) printf("\n"); printf("Collection #%d:\n",++kase); if(dp[v] == v) printf("Can be divided.\n\n"); else printf("Can't be divided.\n\n"); } } return 0; }