【动态规划】多重背包

问题 I: 【动态规划】多重背包

时间限制: 1 Sec  内存限制: 64 MB
提交: 11  解决: 10
[提交][状态][讨论版]

题目描述

张琪曼:“魔法石矿里每种魔法石的数量看起来是足够多,但其实每种魔法石的数量是有限的。”

李旭琳:“所以我们需要改变装包策略啦。”

现有N(N≤10)种魔法石和一个容量为V(0<V<200)的背包。第i种魔法石最多有n[i]件可用,每个占用的空间是c[i],价值是w[i]。全部物品总数不超过50。求解将哪些魔法石装入背包可使这些物品的容量总和不超过背包容量,且价值总和最大。

输入

第一行为两个数字,即V和N。以下N行为每种物品的空间,价值和数量。

输出

最大价值总和。

样例输入

8 2
2 100 4
4 100 2

样例输出

400

代码:
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int V,N;
int v[1005];
int w[1005];
int c[1005];

int a[1005];

void zeroonepack(int T,int t,int p){//总容量,单件物品消耗,单件价值
    for(int i=T;i>=t;i--){
        a[i]=max(a[i],a[i-t]+p);
    }
}


void completepack(int T,int t,int p){//总重量,单件物品消耗,单件价值
    for(int i=t;i<=T;i++){
        a[i]=max(a[i],a[i-t]+p);
    }
}

void multiplepack(int V,int v,int w,int m){//剩余容量,消耗,价值,数量
    int k;
    if(v*m>=V){//如果这一种物品就能把背包装满可以当完全背包来放。
        completepack(V,v,w);
        return ;
    }
    k=1;
    while(k<=m){
        zeroonepack(V,k*v,k*w);
        m=m-k;
        k*=2;
    }
    zeroonepack(V,v*m,w*m);
}

int main()
{
    while(scanf("%d %d",&V,&N)!=EOF){
        for(int i=0;i<N;i++){
            scanf("%d %d %d",&v[i],&w[i],&c[i]);
        }
        for(int i=0;i<N;i++){
            multiplepack(V,v[i],w[i],c[i]);
        }
        printf("%d\n",a[V]);
    }

    return 0;
}

 

 
posted @ 2016-08-16 11:10  多一份不为什么的坚持  阅读(343)  评论(0编辑  收藏  举报