多重背包问题
有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N≤1000
0<V≤2000
0<vi,wi,si≤2000
提示:
本题考查多重背包的二进制优化方法。
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
观察发现这个数据远远大于一般的多重背包问题
所以机智的我就出现了二进制优化!!!
先看代码
就是把多重背包转换为01背包
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int n,m,s[10000],vv[10000],v[100000],ww[100000],w[100000],i,j,k,t,d[10000000];
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d%d%d",&vv[i],&ww[i],&s[i]);
for(i=0;i<=m;i++)
d[i]=0;
k=1;
for(i=1;i<=n;i++)
{
for(j=1;j<s[i];j*=2)//二进制优化过程
{
v[k]=j*vv[i],w[k]=j*ww[i];
k++;
s[i]-=j;
}
if(s[i])
{
v[k]=s[i]*vv[i],w[k]=s[i]*ww[i];
k++;
}
}
k=k-1;//多算的1
//这个是看看优化后的
//for(i=1;i<=k;i++)
//printf("%d %d\n",v[i],w[i]);
//01背包他又来了
for(i=1;i<=k;i++)
for(j=m;j>=v[i];j--)
{
d[j]=max(d[j],d[j-v[i]]+w[i]);
}
printf("%d\n",d[m]);
}
为什么要用二进制??
自己悟!