您的位置:首页 > 其它

动态规划[入门3]-多重背包问题

2015-10-12 10:45 375 查看
分析:这个和我们之前讲的0-1背包问题很像。

思路1:
我们显然可以把每种物品的每一件都作为一个新的物品按照普通0-1背包的方法做。
但是0-1背包的时间复杂度是O(W * N) , 这里N = C1 + C2 + …+ Cn。

思路2:
换个角度我们用dp[i][j]表示前i件物品,总重量为j的时候的最大价值。
则dp[i][j] = max{dp[i – 1][j – k * Wi] + k * Vi}
其中 0 ≤ k ≤ min( j / Wi , Ci)

这个的时间复杂度是n * W * max(Ci)

最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。

输入

第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)


输出

输出可以容纳的最大价值。


输入示例

3 6
2 2 5
3 3 8
1 4 1


输出示例

9


请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。

line=input().split()
n=int(line[0])
m=int(line[1])
w=[]
p=[]
c=[]
for i in range(n):
line=input().split()
tw=int(line[0])
tp=int(line[1])
tc=int(line[2])
k=1
while tc>=k:
w.append(k*tw)
p.append(k*tp)
tc-=k
k*=2
if tc>0:
w.append(tc*tw)
p.append(tc*tp)
n2=len(w)
f=[]
for i in range(m+1):
f.append(0)
for i in range(n2):
for j in range(m,w[i]-1,-1):
f[j]=max(f[j],f[j-w[i]]+p[i])
print(f[m])


又超时!!

#include<cstdio>
int max(int a,int b){
if (a>b) return a;
else return b;
}
int main(){
int n,m,c,tw,tp;
int w[1000],p[1000],f[50000];
scanf("%d%d",&n,&m);
int j=-1;
for(int i=0;i<n;i++){
scanf("%d%d%d",&tw,&tp,&c);
int k=1;
while (c>=k){
j++;
w[j]=tw*k;
p[j]=tp*k;
c-=k;
k*=2;
}
if (c>0){
j++;
w[j]=tw*c;
p[j]=tp*c;
}
}
int n2=j+1;
for(int i=0;i<=m;i++){
f[i]=0;
}
for(int i=0;i<n2;i++){
for(int j=m;j>=w[i];j--){
f[j]=max(f[j],f[j-w[i]]+p[i]);
}
}
printf("%ld",f[m]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: