题目描述:
有1-6重量的物品。给出一个数列分别代表这些重量的物品的数量。求这些物品是否能被平分为两堆等重的物品。
解题思路:
把总重量的一半作为容量上限,把重量作为判定价格。定义F[v]为最接近v重量的物品能凑成的重量。
代码:
#include <stdio.h>
#include <stdlib.h>
#define V 60200
int f[V];
main()
{
int set[7];
int sum=0, i, k, v, count = 1, c, s;
for(i=1;i<=6;i++)
{
scanf("%d",&set[i]);
sum += set[i]*i;
}
while(sum!=0)
{
printf("Collection #%d:\n",count++);
if(0 == sum%2)
{
memset(f,0,sizeof(int)*(sum/2+1));//int f[] = {0};
for(i=1;i<=6;i++)
{
c = set[i];
k = 1;
while(c >= k)
{
for(v = sum/2;v>=k*i;v--)
if(f[v-k*i]+k*i <= v)
f[v] = f[v]>f[v-k*i]+k*i ? f[v]:f[v-k*i]+k*i;
c -= k;
k*=2;
}
if(0 != c)
{
k = c;
for(v = sum/2;v>=k*i;v--)
if(f[v-k*i]+k*i <= v)
f[v] = f[v]>f[v-k*i]+k*i ? f[v]:f[v-k*i]+k*i;
}
}
if(f[sum/2] == sum/2)
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
else
printf("Can't be divided.\n\n");
sum = 0;
for(i=1;i<=6;i++)
{
scanf("%d",&set[i]);
sum += set[i]*i;
}
}
//system("pause");
return 0;
}