http://acm.hdu.edu.cn/showproblem.php?pid=1059
题意: 有两个人一起收集石头 石头的重量有六种 每种都有一定的数量
现在两人想要将所有石头按重量来平分 问 可不可以做到
思路:
这题可以用多重背包解决
把多重背包转化为01背包 如果dp[tot/2]==1 则可以平分
否则不能
因为数量较多 还要加个二进制优化
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <iostream> #include <queue> #include <algorithm> typedef long long LL; using namespace std; int dp[121000]; int main() { int a[10],ca = 1,e = 0; while (scanf("%d",&a[1])) { int i,j; for(i = 2; i<=6; i++) scanf("%d",&a[i]); int cnt = 0; for(i = 1; i<7;i++) { if(a[i] == 0) cnt++; } if(cnt == 6) break; if(e++) printf(" "); cnt = 0; for(i = 1; i<=6; i++) cnt+=i*a[i]; printf("Collection #%d: ",ca++); if(cnt%2 ==1 ) { cout<<"Can't be divided."<<endl; continue; } int ans = cnt/2; memset(dp,-1,sizeof(dp)); dp[0] = 1; int k; for(i = 1; i<7; i++) //石头重量为 i { int tot = a[i];// 重量为 i 的石头 有 tot个 for(j = 1; j <= tot;j*=2)// j 个石头 { tot -= j; for(k = ans;k>=i*j;k--)// 当前状态 { int w = i*j; if(dp[k - w] !=-1) dp[k] = 1; } } if(tot!=0) { for(k = ans;k>=i*tot;k--) { int w = i*tot; if(dp[k - w] !=-1) dp[k] = 1; } } } if(dp[ans] == 1) cout<<"Can be divided."<<endl; else cout<<"Can't be divided."<<endl; } return 0; }