- 题目链接: 1059 Dividing
- 题意: 有6个物品,一个物品的价值=该物品的编号i (1-6),给定每个物品的数量,问,是否能将所有物品分成价值相等的两堆?
- 解法: 多重背包,将价值当作背包承受量,物品数量当作价值.
int a[7];
int f[120005];
int v,k;
void ZeroOnePack(int cost,int weight)//cost 为费用, weight 为价值
{
for(int i=v;i>=cost;i--)
if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight;
}
void CompletePack(int cost,int weight)
{
for(int i=cost;i<=v;i++)
if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight;
}
void MultiplePack(int cost ,int weight,int amount)
{
if(cost*amount>=v) CompletePack(cost,weight);
else
{
for(int k=1;k<amount;)
{
ZeroOnePack(k*cost,k*weight);
amount-=k;
k<<=1;
}
ZeroOnePack(amount*cost,amount*weight);
}
}
int main()
{
int tol;
int iCase=0;
while(1)
{
iCase++;
tol=0;
for(int i=1;i<7;i++)
{
scanf("%d",&a[i]);
tol+=a[i]*i;//总价值数
}
if(tol==0) break;
if(tol%2==1)
{
printf("Collection #%d:\nCan't be divided.\n\n",iCase);
continue;
}
else
{
v=tol/2;
memset(f,0,sizeof(f));
for(int i=1;i<7;i++)
MultiplePack(i,i,a[i]);
if(f[v]==v)
printf("Collection #%d:\nCan be divided.\n\n",iCase);
else printf("Collection #%d:\nCan't be divided.\n\n",iCase);
}
}
return 0;
}