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





  • 相关阅读:
    Post返回json值
    调用接口并获取放回json值
    c# 获取IP
    sqlserver2008不允许保存更改
    判断客户端是否是手机或者PC
    3.docker tomcat集群
    1.docker 安装
    Maven profiles 多环境配置
    MySQL 定时任务
    MyBatis 三剑客
  • 原文地址:https://www.cnblogs.com/gt123/p/3457946.html
Copyright © 2011-2022 走看看