多重背包
整体思路:转为01背包
使用二进制优化,将每一类物品都打包,最后选择一包包的要不要选
N开多大?
nlogs(其中n是类别数,s是每个类的数量)
为什么是logs? 最差情况是logs
为什么,思考一下:2^0+2^1+2^2+2^3=2^4-1 也就是对于s=16个物品,logs=4
2^0+2^1+2^2+2^3=15 这里是四包 最后剩出来的1个分成一包,(1<16)
代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 12000,M = 2010;
int w[N],v[N];//打包后的每一包的价值和体积
int dp[M];
int n,m;
int main()
{
cin>>n>>m;
int k=1; //打成了几包
for(int i=1;i<=n;i++)
{
int value,volum,s;
cin>>volum>>value>>s;
int a=1;
while(a<=s)
{
s-=a;
w[k]=a*value;
v[k]=a*volum;
a*=2;
k++;
}
if(s)
{
w[k]=s*value;
v[k]=s*volum;
k++;
}
}
k--;
for(int i=1;i<=k;i++)
for(int j=m;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
cout<<dp[m];
return 0;
}