zoukankan      html  css  js  c++  java
  • HDU--2844 Coins(多重背包)

    题目http://acm.hdu.edu.cn/showproblem.php?pid=2844

    题目分析 给定N和M,N表示硬币的种类,M表示最大不超过的总价值,
    相当于背包的重量或体积等一类的限制条件。A[1....N]表示硬币的面值
    C[1....N]表示相应的硬币的数目。
    求能用这些硬币组合成多少种金额(金额在1~M之间)?
    转换为背包问题就是1~M中间的数值能否可以被组成。通常所做的背包是
    求最大值是那种金额?这里我们如果可以到某一个值i那么令dp[i]=1表示可以取到。
    #include<stdio.h>

    int M,dp[100001];

    //O1背包
    void ZeroOnePack(int c,int w)
    {
      for(int i=M;i>=c;i--)
        dp[i]=dp[i]|dp[i-c];
    }
    //完全背包
    void CompletePack(int c,int w)
    {
      for(int i=c;i<=M;i++)
        dp[i]=dp[i]|dp[i-c];
    }
    //多重背包
    void MultiplePack(int c,int w,int n)
    {
      if(c*n>=M)
      {
        CompletePack(c,w);
        return;
      }
      int k=1;
      while (k<=n)
      {
        ZeroOnePack(k*c,k*w);
        n-=k;
        k*=2;
      }
      ZeroOnePack(n*c,n*w);
    }

    int main()
    {
      int N,a[101],c[101];
      while (scanf("%d%d",&N,&M)!=EOF)
      {
        if(!N&&!M) break;
        for(int i=1;i<=N;i++)
          scanf("%d",&a[i]);
        for(int i=1;i<=N;i++)
          scanf("%d",&c[i]);
          
        //初始化需要注意,dp[0]表示一种方案满足金额为0  dp[1...M]初始化为没有方案满足
        //这里的dp[i]表示根据是否又满足金额为i 是为1 否为0
        for(int i=0;i<=M;i++)
          dp[i]=0;
        dp[0]=1;

        for(int i=1;i<=N;i++)
          MultiplePack(a[i],a[i],c[i]);

        int sum=0;
        for(int i=1;i<=M;i++)
          sum+=dp[i];

        printf("%d ",sum);
      }
      return 0;
    }





  • 相关阅读:
    代码性能优化-1
    sql调优-1
    2020.11.08 字符串可以是对象
    2020.11.09 JavaScript运算符
    2020.11.10 JavaScript 比较
    2020.11.11
    2020.11.12 条件语句
    2020.11.13 switch语句
    2020.11.14 循环
    2020.11.15
  • 原文地址:https://www.cnblogs.com/gt123/p/3457946.html
Copyright © 2011-2022 走看看