5429 多重背包

5429 多重背包

 

 时间限制: 1 s
 空间限制: 256000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 Description

你有一个容量为M的背包,和N种物品。

每种物品都有三个属性,vi,wi,与ci,分别表示这种物品的体积、价值和件数。

你的任务是,从这些所给物品中,选出若干件,其体积之和不能超过背包容量,并且使所选物品的权值的和最大。

输入描述 Input Description

第一行两个整数N,M

接下来N行每行三个数vi,wi,ci描述第i件物品的属性

输出描述 Output Description

最大的权值和

样例输入 Sample Input

2 8

2 100 4

4 100 2

样例输出 Sample Output

400

数据范围及提示 Data Size & Hint

对于20%的数据,ci=1

对于60%的数据,N,M<=500,ci<=100

对于100%的数据,N,M<=3000,ci<=3000,保证答案不超过2147483647

分类标签 Tags 点此展开 

 
暂无标签
题解:
二进制优化的背包
ps:数据有点超,数组要开大点
AC代码:
#include<cstdio>
#include<iostream>
using namespace std;
inline int read(){
    register int x=0,f=1;
    register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int N=1e5+10;
int n,m,cnt,xp[30];
int f[N*200],v[N],c[N];
int main(){
    for(int i=0;i<=25;i++) xp[i]=1<<i; 
    n=read();m=read();
    for(int i=1,x,y,z;i<=n;i++){
        x=read();y=read();z=read();
        for(int t=0;z>xp[t];t++){
            v[++cnt]=x*xp[t];
            c[cnt]=y*xp[t];
            z-=xp[t];
        }
        if(z>0){
            v[++cnt]=x*z;
            c[cnt]=y*z;
        }
    }
    for(int i=1;i<=cnt;i++){
        for(int j=m;j>=v[i];j--){
            f[j]=max(f[j],f[j-v[i]]+c[i]);
        }
    }
    printf("%d",f[m]);
    return 0;
}
原文地址:https://www.cnblogs.com/shenben/p/5967780.html