【DP合集】背包 bound

N 种物品,第 i 种物品有 s i 个,单个重量为 w i ,单个价值为 v i 。现有一个限重为 W 的背包,求能容 纳的物品的最大总价值。

Input

输入第一行二个整数 N , W ( N ≤ 1000 , M ≤ 10000) 。 
接下来 N 行,每行三个整数 s i,w i,v i ,描述一种物品。

Output

输出一行一个整数,描述能容纳的物品的最大总价值。保证答案不会超过2311231−1 。

 

题解:

单个单个枚举会超时,所以可以用二进制优化,就是因为如果我们可以将任意一个十进制数化成二进数,所以我可以把n个一样的背包,拆成二进制数上对于1的数的数量个背包,所以就把n个背包合并成logn个大背包,如果还不会可以参考ACM P217。
 
代码
复制代码
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[100000],v[100000],w[10000],len=0;
 
void cl(){
    memset(dp,0,sizeof(dp));
    memset(v,0,sizeof(v));
    memset(w,0,sizeof(w));
}
 
int main(){
    cl();
    int n,m;                                    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        int s,ww,vv,x=1;
        scanf("%d%d%d",&s,&ww,&vv);
        while(s-x>0){
            v[++len]=vv*x;
            w[len]=ww*x;
            s-=x;
            x*=2;
        }
        if(s){
            v[++len]=vv*s;
            w[len]=ww*s;
        }
    }
    dp[0]=0;
    for(int i=1;i<=len;i++)
    for(int j=m;j>=w[i];j--)
    dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    printf("%d",dp[m]);
}
复制代码

 

posted @   人间失格—太宰治  阅读(248)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示