题意:每一行输入的6个数,第i个数表示价值为i的珠宝的个数,问这些珠宝是不是能等价平分给两个人。
方法:就是组合数学中的母函数,不会的去学下就会了(可以尝试下hdu1028,比这题简单些),这题的难点在于题目中说每种珠宝的数量最多有20000个,如果不进行一些优化是会超时的,优化的方法就是当每种珠宝的个数n>=8是,可以令n=11(n为奇数)or =12(n为偶数),然后就OK了。还有一个坑就是每个案例要输出一个空行
AC代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<stack>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=150005;
int main()
{
int t,i,j,k,ans,y,n,kase,sum;
int a[maxn],x[maxn],b[maxn];
//cin>>t;
for(kase=1;;kase++)
{
sum=0;
for(i=1;i<=6;i++)
{
cin>>x[i];
if(x[i]>=8)
{
if(x[i]%2==0)
{
x[i]=12;
}
else
{
x[i]=11;
}
}
sum+=i*x[i];
}
if(sum==0)
{
break;
}
printf("Collection #%d:\n",kase);
if(sum%2!=0)
{
cout<<"Can't be divided."<<endl;
cout<<endl;
continue;
}
n=sum/2;
memset(a,0,sizeof(a));
a[0]=1;
for(i=1;i<=6;i++)
{
if(x[i]==0)
{
continue;
}
memset(b,0,sizeof(b));
for(j=0;j<=x[i];j++)
{
for(k=0;(k+j*i)<=n;k++)
{
b[k+j*i]+=a[k];
}
}
for(k=0;k<=n;k++)
{
a[k]=b[k];
}
if(a[n]!=0)
{
break;
}
/* for(j=0;j<=10;j++)
{
cout<<a[j]<<" ";
}
cout<<endl;
cout<<a[n]<<endl;*/
}
if(a[n]==0)
{
cout<<"Can't be divided."<<endl;
}
else
{
cout<<"Can be divided."<<endl;
}
cout<<endl;
}
return 0;
}