poj 1014 _ 多重背包

来源:互联网 发布:mysql更换引擎 编辑:程序博客网 时间:2024/05/22 04:47

题目描述:

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