#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;
}
}
}