#include <stdio.h>
#include <string.h>
#define Size 60005
#define Max(a,b) a>b?a:b
int sum;
int dp[Size];
/*01背包*/
void ZeroOnePack(int cost,int weight)
{
int i;
for(i = sum;i>=cost;i--)
dp[i] = Max(dp[i],dp[i-cost]+weight);
}
/*完全背包*/
void CompletePack(int cost,int weight)
{
int i;
for(i=cost;i<=sum;i++)
dp[i] = Max(dp[i],dp[i-cost]+weight);
}
/*多重背包*/
void MulPack(int cost,int weight,int count)
{
int i;
if(cost*count>=sum)
{
CompletePack(cost,weight);
return ;
}
i = 1;
/*二进制划分*/
while (i<count)
{
ZeroOnePack(i*cost,i*weight);
count-=i;
i<<=1;
}
ZeroOnePack(count*cost,count*weight);
}
int main()
{
int num[7],no = 1,i;
while (1)
{
sum = 0;
for(i=1;i<=6;i++)
{
scanf("%d",&num[i]);
sum+=num[i]*i;
}
if(!sum)
break;
if(sum&1)
printf("Collection #%d:\nCan't be divided.\n\n",no++);
else
{
sum>>=1;
for(i=0;i<=sum;i++)
dp[i] = 0;
for(i=1;i<=6;i++)
if(num[i])
MulPack(i,i,num[i]);
if(dp[sum] == sum)
printf("Collection #%d:\nCan be divided.\n\n",no++);
else
printf("Collection #%d:\nCan't be divided.\n\n",no++);
}
}
return 0;
}
2. 母函数版本
#include <iostream>
using namespace std;
int main()
{
int cnt[7];
int p[7];
for(int i = 0; i <= 6; i++)
p[i] = i;
int t = 0;
while(cin >> cnt[1] >> cnt[2] >> cnt[3] >> cnt[4] >> cnt[5] >> cnt[6],
cnt[1] || cnt[2] || cnt[3] || cnt[4] || cnt[5] || cnt[6])
{
t++;
int Max = 0;
for(int i = 1; i <= 6; i++)
{
cnt[i] %= 30; //重点,不加这句会超时
Max += cnt[i] * p[i];
}
if(Max % 2)
{
printf("Collection #%d:\n", t);
printf("Can't be divided.\n\n");
continue;
}
Max = Max / 2;
int *c1 = new int[Max + 1];
int *c2 = new int[Max + 1];
for(int i = 0; i < Max + 1; i++)
{
c1[i] = 0;
c2[i] = 0;
}
for(int i = 0; i <= cnt[1]; i++)
{
c1[i] = 1;
c2[i] = 0;
}
for(int i = 2; i <= 6; i++)
{
for(int j = 0; j <= Max; j++)
{
int num = cnt[i] * p[i];
for(int k = 0; k <= num && k + j <= Max; k += p[i])
{
c2[k+j] += c1[j];
}
}
for(int j = 0; j <= Max; j++)
{
c1[j] = c2[j];
c2[j] = 0;
}
if(c1[Max])
break;
}
int flag = 0;
if(c1[Max] != 0)
flag = 1;
delete [] c1;
delete [] c2;
printf("Collection #%d:\n", t);
if(flag == 0)
printf("Can't be divided.\n\n");
else
printf("Can be divided.\n\n");
}
return 0;
}