N 种物品,第 i 种物品有 s i 个,单个重量为 w i ,单个价值为 v i 。现有一个限重为 W 的背包,求能容 纳的物品的最大总价值。
Input
输入第一行二个整数 N , W ( N ≤ 1000 , M ≤ 10000) 。
接下来 N 行,每行三个整数 s i,w i,v i ,描述一种物品。
Output
输出一行一个整数,描述能容纳的物品的最大总价值。保证答案不会超过231−1231−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]); }