• HDU--1059 Dividing(多重背包)


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1059
    分析:有一堆石头2个人按照其价值均分,石头的价值分为六个等级1,2,3,4,5,6 
    每一个等级有n[i]个石头也可能一个石头也没有。于是两个人按照总价值进行均分。
    因为每一个等级的石头个数是不等的n[i],这是一个多重背包的问题。可以将背包的容量
    看成是一个总价值的二分之一。并且要求装满。
    #include<stdio.h>

    const int INF=0XFFFFFF;

    int V,dp[120005];

    //01背包
    void ZeroOnePack(int cost,int weight)
    {
      for(int i=V;i>=cost;i--)
        dp[i]=dp[i]>dp[i-cost]+weight?dp[i]:dp[i-cost]+weight;
    }
    //完全背包
    void CompletePack(int cost,int weight)
    {
      for(int i=cost;i<=V;i++)
        dp[i]=dp[i]>dp[i-cost]+weight?dp[i]:dp[i-cost]+weight;
    }
    //多种背包
    void MultiplePack(int cost,int weight,int amount)
    {
      if(cost*amount>=V)
      {
        CompletePack(cost,weight);
        return;
      }
      int k=1;
      while (k<=amount)
      {
        ZeroOnePack(k*cost,k*weight);
        amount-=k;
        k*=2;
      }
      ZeroOnePack(amount*cost,amount*weight);
    }

    int main()
    {
      int n[7],sum,k=1;;
      while (1)
      {
        sum=0;
        for(int i=1;i<=6;i++)
        {
            scanf("%d",&n[i]);
            sum+=i*n[i];
        }
        if(!n[1]&&!n[2]&&!n[3]&&!n[4]&&!n[5]&&!n[6]) break;

        printf("Collection #%d: ",k++);
        //总价值必须是偶数,否则无法均分
        if(sum&1) printf("Can't be divided. ");
        else
        {
          //初始化
          V=sum/2;
          for(int i=0;i<=V;i++)
            dp[i]=-INF;
          dp[0]=0;

          //多重背包
          for(int i=1;i<=6;i++)
            MultiplePack(i,i,n[i]);

          if(dp[V]>0)
             printf("Can be divided. ");
          else
             printf("Can't be divided. ");
        }
      }
      return 0;
    }






  • 相关阅读:
    JAVA程序员面试之《葵花宝典》
    61条Java面向对象设计的经验原则
    悟透JavaScript
    61条Java面向对象设计的经验原则
    悟透JavaScript
    SQL与Oracle数据库镜像对比
    21条SQL Server数据库开发经验
    VB开发——复制Excell表格
    国外Web2.0介绍
    关于RSS
  • 原文地址:https://www.cnblogs.com/gt123/p/3457232.html
Copyright © 2020-2023  润新知