题意:现有面值为1、2、3、4、5、6的硬币若干枚,现在需要知道能不能将这些硬币分成等额的两堆。
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+6;
int dp[maxn],num[10],v[maxn];
int main() {
int kase=0;
while(cin>>num[1]>>num[2]>>num[3]>>num[4]>>num[5]>>num[6]){
memset(dp,0,sizeof(dp));
if(!num[1]&&!num[2]&&!num[3]&&!num[4]&&!num[5]&&!num[6])break;
printf("Collection #%d:\n",++kase);
int sum=num[1]*1+num[2]*2+num[3]*3+num[4]*4+num[5]*5+num[6]*6;
if(sum%2){
cout<<"Can't be divided."<<endl<<endl;;
continue;
}
sum=sum/2;
int cnt=0;
for(int i=1;i<=6;i++){
for(int j=1;j<=num[i];j=j*2){
v[++cnt]=j*i;
num[i]-=j;
}
if(num[i]>0)v[++cnt]=num[i]*i;
}
for(int i=1;i<=cnt;i++)
for(int j=sum;j>=v[i];j--)
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
if(dp[sum]==sum)cout<<"Can be divided."<<endl<<endl;
else cout<<"Can't be divided."<<endl<<endl;;
}
}