题意:每行输入6个数,第i个数代表第i种珠宝的个数,第i种珠宝的价值为i
问:能否把这些珠宝按价值平均分,也就是问这些珠宝是否能组合成总价值的1/2
我是按母函数做的,也可以按多重背包做
如果不对数据处理也可以直接过,不过很费时(900多毫秒。。。。。)
还是应该对数据做一下处理,假设某种珠宝非常多,其实可以把它的数量减少到一定的量,但是依然不影响问题的答案,我们要做的就是找到减少到多少合适
一开始想的是直接把数据%2,但是不对,比如3个5和5个3 这种数据就过不了
看了网上的材料,说是利用抽屉原理(但是没发现和抽屉原理有什么关系)
看一下分析 某种物品有n个,是否可以减少到n-2?
1.如果不能平均分,减少到n-2 还是不能(反证法)
2.如果可以平均分,1)两堆都有这种物品,则可以减少到n-2
2)只有一堆有,则可以用另一堆的物品和这一堆的交换,并使两堆都有这种物品,然后就可以n-2了
如:左边有3个2,右边有一个4,交换一下则左边有1个2和1个4,又边有2个2,然后左右两边就可以各自减一了
然后对1-6具体分析,分析时保证第二堆无论是几都可以满足1)2)条件,则可以把n减少到n-2*n0个了
#include<iostream>
using namespace std;
int a[120001],b[120001];
int main()
{
std::ios::sync_with_stdio(false);
int aa[6];
int t=0;
while(cin>>aa[0]>>aa[1]>>aa[2]>>aa[3]>>aa[4]>>aa[5])
{
int flag=0;
for(int i=0;i<6;i++) if(aa[i]) flag=1;
if(flag==0) break;
t++;
int tot=0;
if(aa[0]>6)
{
if(aa[0]%2) aa[0]=5;
else aa[0]=6;
}
if(aa[1]>5)
{
if(aa[1]%2) aa[1]=5;
else aa[1]=4;
}
if(aa[2]>5)
{
if(aa[2]%2) aa[2]=5;
else aa[2]=4;
}
if(aa[3]>5)
{
if(aa[3]%2) aa[3]=5;
else aa[3]=4;
}
if(aa[4]>6)
{
if(aa[4]%2) aa[4]=5;
else aa[4]=6;
}
if(aa[5]>5)
{
if(aa[5]%2) aa[5]=5;
else aa[5]=4;
}
for(int i=0;i<6;i++) tot+=aa[i]*(i+1);
if(tot%2)
{
cout<<"Collection #"<<t<<":"<<endl;
cout<<"Can't be divided."<<endl<<endl;
continue;
}
for(int i=0;i<=tot/2;i++)
{
a[i]=0;b[i]=0;
}
a[0]=1;
for(int i=0;i<6;i++)
{
if(aa[i]==0) continue;
for(int j=0;j<=tot/2;j++)
{
if(a[j]==0) continue;
for(int k=0;k*(i+1)+j<=tot/2&&k<=aa[i];k++) b[k*(i+1)+j]+=a[j];
}
for(int j=0;j<=tot/2;j++)
{
a[j]=b[j];
b[j]=0;
}
}
if(a[tot/2])
{
cout<<"Collection #"<<t<<":"<<endl;
cout<<"Can be divided."<<endl<<endl;
}
else
{
cout<<"Collection #"<<t<<":"<<endl;
cout<<"Can't be divided."<<endl<<endl;
}
}
}