1086 背包问题 V2
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注
有N种物品,每种物品的数量为C1,C2……Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。
Input
第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000)
第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)
Output
输出可以容纳的最大价值。
Input示例
3 6
2 2 5
3 3 8
1 4 1
Output示例
9
相关问题
多重背包是每种物品有一定的数量
题上为例
我们可以发现
将01背包的代码 按照每种物品的数量输入的时候
得到的结果就是正确答案
但是肯定的是
如果直接用这种思想做的话会超时
所以要多一步的优化
我们 将第一件物品变成k个种类的物品
首先
体积 价值 物品剩余数量
2 2 4
4 4 2
4 4 0 最后一步的处理是为了让剩余的物品变成一类物品
3 3 7
6 6 5
12 12 1
3 3 0
以上步奏就是对于多重背包关于01背包的优化
#include <iostream>
#include <stdio.h>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
long long d[100000],p[100000];
int main()
{
long long t,v;
long long n1[1000],w1[100],s1[1000];
long long n[100000],w[100000];
while(cin>>t>>v)
{
memset(n,0,sizeof(n));
memset(w,0,sizeof(w));
memset(d,0,sizeof(d));
memset(p,0,sizeof(p));
memset(w1,0,sizeof(w1));
memset(n1,0,sizeof(n1));
memset(s1,0,sizeof(s1));
long long i,x=0,y,j=0,r=1;
for(i=0;i<t;i++)
{
cin>>n1[i]>>w1[i]>>s1[i];
x=n1[i];
y=w1[i];
r=1;
for(;;)
{
if(s1[i]-r<0)
{
n[j]=n1[i]*s1[i];
w[j]=w1[i]*s1[i];
j++;
break;
}
n[j]=x;
w[j]=y;
s1[i]-=r;
j++;
r*=2;
x=x*2;
y=y*2;
}
j++;
}
t=j;
/*for(i=0;i<t;i++) cout<<n[i]<<' '<<w[i]<<endl;*/
for(i=1;i<=t;i++)
{
for(j=0;j<=v;j++) p[j]=d[j];
for(j=n[i-1];j<=v;j++)
{
d[j]=max(p[j-n[i-1]]+w[i-1],p[j]);
}
}
cout<<d[v]<<endl;
}
return 0;
}