完全背包问题和多重背包问题....
在理解01背包问题之后完全背包和多重背包感觉就好理解了...
完全背包题目链接:22背包专题 [Cloned] - Virtual Judge (vjudge.net)
题目思路:在01 背包的基础上加了每个物品可以拿无数次,那比较的就不是和上一行和这一行减去第i个商品后的空间然后加上第i个物品的总价值谁高了。
然后二维优化成一维就不用从后开始了,因为此时从小开始拿物品已经要影响后面的价值了,所以一维的时候就要从前开始了..
转台转移方程就是:mjz[j]=max(mjz[j-w[i]]+jz[i],mjz[j]);
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int mjz[50005];
int w[1005],jz[1005];
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d %d",&w[i],&jz[i]);
}
for(int i=1;i<=n;i++){
for(int j=w[i];j<=m;j++){
mjz[j]=max(mjz[j-w[i]]+jz[i],mjz[j]);
}
}
printf("%d",mjz[m]);
}
多重背包问题:就是每个物品有有限的次数拿取..
题目链接:22背包专题 [Cloned] - Virtual Judge (vjudge.net)
主要思路:那就可以把每种物品都展开,展开之后就是01背包的问题了...
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int mjz[50005];
int w[50005],jz[50005];
int main(){
int n,m,sum;
cin>>n>>m;
sum=1;
for(int i=1;i<=n;i++){int w1,jz1,t;
cin>>w1>>jz1>>t;
while(t--){
w[sum]=w1;
jz[sum]=jz1;
sum++;
}
}
for(int i=1;i<=sum-1;i++){
for(int j=m;j>=w[i];j--){
mjz[j]=max(mjz[j-w[i]]+jz[i],mjz[j]);
}
}
cout<<mjz[m];
}