背包问题总结
如下是各个背包之间的关系
01背包
核心代码
//注意是一维滚动数组,所以是倒推,防止物品被多次取用
for(int i=0;i<n;i++){//n-->物品数量
for(int j=m;j>=w[i];j--){//m-->最大背包质量;w[]-->物品质量数组
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);//dp[j]-->在背包容量为j时,能装下的最大价值;v[]-->物品的价值数组;m-->背包的最大容量
}
}
完全背包
核心代码
//仍然采用一维数组,但是要正推,让物品被多次取用
for(int i=1;i<n;i++){//参数与01背包一致
for(int j=1;j<=m;j++){
if(j>=w[i])
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
多重背包
核心代码
//由于物品有取用的数量限制,所以可以将每个物品看作不同物品
for(int i=0;i<n;i++){//n-->物品数量
for(int k=1;k<=c[i];k++){//数量遍历
for(int j=m;j>=w[i];j--){//m-->最大背包质量;w[]-->物品质量数组
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);//dp[j]-->在背包容量为j时,能装下的最大价值;v[]-->物品的价值数组;m-->背包的最大容量
}
}
}
分组背包
核心代码
//由于物品有取用的数量限制,所以可以将每个物品看作不同物品
for(int i=0;i<n;i++){//n-->物品数量
for(int k=1;k<=c[i];k++){//c[i]-->每一组中的物品个数
for(int j=m;j>=w[i];j--){//m-->最大背包质量;w[]-->物品质量数组
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);//dp[j]-->在背包容量为j时,能装下的最大价值;v[]-->物品的价值数组;m-->背包的最大容量
}
}
}
混合背包
核心代码
01背包+完全背包+多重背包
for(int i=0;i<n;i++){
if(i是01背包物品){
for(int j=m;j>0;j--){
.......//转换方程
}
}
else if(i是完全背包){
for(int j=0;j<=m;j++){
......//转换方程
}
}
else if(i是多重背包){
for(int k=1;k<=c[i];k++){
for(int j=m;j>0;j--){
......//转换方程
}
}
}
}