#include<iostream>
#include<algorithm>
#include <cstring>
using namespace std;
//P139
//动态规划
int a[7];//各种价值大理石的块数
int iCase=1;//测试数据组的编号
int sum=0;//预处理之后大理石的总价值
int i;
void DP(int sum)
{
int i,j,k;
//大理石块总价值的一半
int mid=sum/2;
//大理石的状态数组
char visit[200];
memset(visit,0,sizeof(visit));
int t;
visit[0]=1;//初值
//对每种价值的大理石块
for(i=1; i<=6; i++)
for(j=mid; j>=0; j--)
//价值为j的分配方案存在
if(visit[j])
for(k=1; k<=a[i]; k++)
{
t=j+i*k;
if(t>mid)
break;
//增加k块价值为i的大理石,该平分方案仍然成立
else
visit[t]=1;
//找到了分配方案
if(t==mid)
{
cout<<"Can be divided."<<endl;
return;
}
}
cout<<"Can't be divided."<<endl;
}
int main()
{
for(i=1; i<=6; i++)
{
cin>>a[i];
//数据预处理
if(a[i]!=0&&a[i]%6==0)
a[i]=6;
else
a[i]=a[i]%6;
sum+=a[i]*i;
}
while(sum!=0)
{
//当和为0时说明是输入结束的标志
cout<<"Collection #"<<iCase++<<":"<<endl;
//总价值为奇数,无法平分
if(sum%2)
{
cout<<"Can't be divided."<<endl;
}
else
{
DP(sum);
}
sum=0;
for(i=1; i<=6; i++)
{
cin>>a[i];
//数据预处理
if(a[i]!=0&&a[i]%6==0)
a[i]=6;
else
a[i]=a[i]%6;
sum+=a[i]*i;
}
}
}
平分大理石块的枚举算法:
#include<iostream>
#include<algorithm>
using namespace std;
//P139
//枚举法
int a[7];//各种价值大理石的块数
int iCase=1;//测试数据组的编号
int sum=0;//预处理之后大理石的总价值
int i;
void enumerate(int sum)
{
int mid;
int i1,i2,i3,i4,i5,i6;
for(i1=0; i1<=a[1]; i1++)
for(i2=0; i2<=a[2]; i2++)
for(i3=0; i3<=a[3]; i3++)
for(i4=0; i4<=a[4]; i4++)
for(i5=0; i5<=a[5]; i5++)
for(i6=0; i6<=a[6]; i6++)
{
mid=1*i1+2*i2+3*i3+4*i4+5*i5+6*i6;
if(mid==sum/2)
{
cout<<"Can be divided."<<endl;
return;
}
}
cout<<"Can't be divided."<<endl;
}
int main()
{
for(i=1; i<=6; i++)
{
cin>>a[i];
//数据预处理
if(a[i]!=0&&a[i]%6==0)
a[i]=6;
else
a[i]=a[i]%6;
sum+=a[i]*i;
}
while(sum!=0){
//当和为0时说明是输入结束的标志
cout<<"Collection #"<<iCase++<<":"<<endl;
//总价值为奇数,无法平分
if(sum%2)
{
cout<<"Can't be divided."<<endl;
}
else
{
enumerate(sum);
}
sum=0;
for(i=1; i<=6; i++)
{
cin>>a[i];
//数据预处理
if(a[i]!=0&&a[i]%6==0)
a[i]=6;
else
a[i]=a[i]%6;
sum+=a[i]*i;
}
}
}