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

    原题链接:点击此处

    解题思路:

    多重背包问题,不太理解,理解了再补充。

    网上博客的思路是:

    对于每个硬币而言:
     
    IF 价值×数量>=m
     
           THEN 取这个硬币的次数相当于无限制,可以考虑成完全背包
     
    ELSE
     
           THEN 考虑成0-1背包(二进制优化),就是把这个硬币的v和num组合出0-1背包可能出现的状态(可以去看背包九讲)
     
    (对于num,类似于编码。  当2^n <=num/2时:k = 2^n(n=012,……)表示状态,对应下来就是二进制的某一位数是1,然后还有一个状态就是k>num/2的时候啦,num+1-k,这样下来就可以用k来组合枚举出从1->num的所有可能了。然后对于k,单位价值和大小都乘上k之后就变成了一个0-1背包)
    View Code

    源代码如下:

    #include <stdio.h>  
    #include <algorithm>  
    #include <string.h>  
    using namespace std;  
      
    const int MAX=100000;  
    int dp[MAX];  
    int c[MAX],w[MAX];  
    int v;  
      
    void ZeroOnePack(int cost,int wei)//01  
    {  
        int i;  
        for(i = v;i>=cost;i--)  
        {  
            dp[i] = max(dp[i],dp[i-cost]+wei);  
        }  
    }  
      
    void CompletePack(int cost,int wei)//完全  
    {  
        int i;  
        for(i = cost;i<=v;i++)  
        {  
            dp[i] = max(dp[i],dp[i-cost]+wei);  
        }  
    }  
      
    void MultiplePack(int cost,int wei,int cnt)//多重  
    {  
        if(v<=cnt*cost)
        {  
            CompletePack(cost,wei);  
            return ;  
        }  
        else
        {  
            int k = 1;  
            while(k<=cnt)  
            {  
                ZeroOnePack(k*cost,k*wei);  
                cnt = cnt-k;  
                k = 2*k;  
            }  
            ZeroOnePack(cnt*cost,cnt*wei);  
        }  
    }  
      
    int main()  
    {  
        int n;  
        while(~scanf("%d%d",&n,&v),n+v)  
        {  
            int i;  
            for(i = 0;i<n;i++)  
            scanf("%d",&c[i]);  
            for(i = 0;i<n;i++)  
            scanf("%d",&w[i]);  
            memset(dp,0,sizeof(dp));  
            for(i = 0;i<n;i++)  
            {  
                MultiplePack(c[i],c[i],w[i]);  
            }  
            int sum = 0;  
            for(i = 1;i<=v;i++)  
            {  
                if(dp[i]==i)  
                {  
                    sum++;  
                }  
            }  
            printf("%d
    ",sum);  
        }  
        return 0;  
    }  
    View Code
  • 相关阅读:
    php 类文件加载 Autoloader
    windows下配置nginx+php
    crontab 定时调度
    PHP 常见语法 集合
    php socket
    tengine + mysql + nginx + php
    yii2 [行为] behaviors 拦截器
    .htaccess 语法以及应用
    nginx 安装
    Nginx HTTP负载均衡和反向代理配置
  • 原文地址:https://www.cnblogs.com/gdvxfgv/p/5767516.html
Copyright © 2011-2022 走看看