zoukankan      html  css  js  c++  java
  • poj 1276 多重背包模板题

    题意:

    给出总的钱币额V,给出n种币值和数目,问最接近V的的组合?

    分析:

    多重背包的模板题,多重背包问题是:
    有N种物品和一个容量为V的背包。第i种物品最多有num[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
    状态转移为:

    F[i,v] = max{F[i−1,v−k∗Ci] + k∗Wi |0 ≤ k ≤ Mi}

    对于本题,币值既是费用也是价值,然后套一下模板搞定。

    
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=100000+9;
    int f[N],w[N],c[N],num[N],V,n;
    void ZeroOnePack(int C,int W)
    {
        for(int v=V;v>=C;v--)
            f[v]=max(f[v],f[v-C]+W);
    }
    void CompletePack(int C,int W)
    {
        for(int v=C;v<=V;v++)
            f[v]=max(f[v],f[v-C]+W);
    }
    int MultiplePack()
    {
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            if(num[i]*c[i]>V)
                CompletePack(c[i],w[i]);
            else{
                int k=1;
                while(k<num[i]){
                    ZeroOnePack(k*c[i],k*w[i]);
                    num[i]-=k;
                    k<<=1;
                }
                ZeroOnePack(num[i]*c[i],num[i]*w[i]);
            }
        }
        return f[V];
    }
    
    int main()
    {
        //freopen("f.txt","r",stdin);
        while(~scanf("%d%d",&V,&n)){
            for(int i=1;i<=n;i++){
                scanf("%d%d",&num[i],&c[i]);
                w[i]=c[i];
            }
            printf("%d
    ",MultiplePack());
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    随机数生成器
    赌博的艺术
    基本算法——包罗万象
    对于搜索的新理解
    关于动态规格的新理解
    发现的好东西——bitset
    高精度(重定义版)——来自
    ac自动机(模板)
    数据采集框架Gobblin简介
    Hadoop的数据采集框架
  • 原文地址:https://www.cnblogs.com/01world/p/5762839.html
Copyright © 2011-2022 走看看