• 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;
    }
    
    
    
  • 相关阅读:
    公平锁与非公平锁源码对比
    内存屏障和volatile内存语义的实现
    熟悉activemq的初步试用
    springMVC中数据流解析与装载
    ubuntu工作常用命令及需要留意的点汇总
    maven相关配置
    ueditor问题
    关于layer的问题
    thymeleaf
    Node Util模块(转存)
  • 原文地址:https://www.cnblogs.com/01world/p/5762839.html
Copyright © 2020-2023  润新知