1. 01背包问题
有N种物品和一个容量为V的背包,每种物品只有一个
第i件物品的体积是v[i],价值是w[i]
问:如何向背包装物体才能使背包中物体的总价值最大?
分析:
每个物品都有2种选择,一种是不选,一种是选
核心代码:
for(int i = 1;i <= N;i++){//枚举物品
for(int j = 0;j <= V;j++){//枚举背包容量
dp[i][j] = dp[i-1][j];//不选第i个物品
if(j >= v[i]){//选第i个物品(但前提是背包容量足以装下这个物品)
dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);
}
}
}
2.完全背包问题
有N种物品和一个容量为V的背包,每种物品有无限多个
第i件物品的体积为v[i],价值是w[i]
问:如何向背包装物体才能使背包中物体的总价值最大?
分析:
每个物品有n种选择,一种是不选,一种是选1个,一种是选2个……
这里我引用了其他博主的,我觉得给我的启发很大,分享给大家:
(1)不放第i件物品,那么dp[i][v] = dp[i-1][v],这步跟01背包是一样的。
(2)放第i件物品。这里的处理和01背包有所不同,因为01背包的每个物品只能选择一个,因此选择放第i件物品就意味着必须转移到dp[i-1][v-w[i]]这个状态;但是完全背包问题不同,完全背包如果选择放第i件物品之后并不是转移到dp[i-1][v-w[i]]这个状态;而是转移到dp[i][v-w[i]],这是因为每种物品可以放任意件(注意有容量的限制,因此还是有限的),放了第i件物品后还可以继续放第i件物品,直到第二维的v-w[i]无法保持大于等于0为止。
核心代码:
for(int i = 1;i <= N;i++){
for(int j = 0;j <= V;j++){
dp[i][j] = dp[i-1][j];//不选第i件物品
if(j >= v[i]){//选择第i件物品(前提是背包容量能装下这件物品)
dp[i][j] = max(dp[i][j],dp[i][j-v[i]]+w[i]);
}
}
}