- 问答
背包方案数
- @ 2025-11-22 20:40:57
样例输入:
4 5
1 2
2 4
3 4
4 6
// 不选当前物品:保持原样
// 选当前物品:从j-v状态继承
int new_val = f[j - v] + w; // 选择后的新价值
if (new_val > f[j]) {
// 找到更好的方案:完全采用新方案
f[j] = new_val;
g[j] = g[j - v]; // 继承:新方案数 = 来源状态的方案数
}
else if (new_val == f[j]) {
// 价值相等:合并方案数
g[j] = g[j] + g[j - v]; // 原有方案 + 新继承的方案
}
初始状态
| 容量 j | f[j] (最大价值) | g[j] (方案数) | 说明 |
|---|---|---|---|
| 0 | 0 | 1 | 空背包,1种方案 |
| 1 | 0 | 暂无方案 | |
| 2 | |||
| 3 | |||
| 4 | |||
| 5 |
处理物品1 (体积=1, 价值=2)
| 容量 j | 原f[j] | 原g[j] | 新f[j] | 新g[j] | 变化说明 |
|---|---|---|---|---|---|
| 5 | 0 | 0 | 0 | j<1,无法选择物品1 | |
| 4 | |||||
| 3 | |||||
| 2 | |||||
| 1 | 2 | 1 | 选择物品1,从g[0]继承方案数1 | ||
| 0 | 1 | 0 | 保持不变 | ||
处理物品2 (体积=2, 价值=4)
| 容量 j | 原f[j] | 原g[j] | 新f[j] | 新g[j] | 变化说明 |
|---|---|---|---|---|---|
| 5 | 0 | 4 | 1 | 选择物品2,从g[3]继承方案数1 | |
| 4 | 选择物品2,从g[2]继承方案数1 | ||||
| 3 | 选择物品2,从g[1]继承方案数1 | ||||
| 2 | 选择物品2,从g[0]继承方案数1 | ||||
| 1 | 2 | 1 | 2 | 不选物品2,保持不变 | |
| 0 | 0 | 保持不变 | |||
处理物品3 (体积=3, 价值=4)
| 容量 j | 原f[j] | 原g[j] | 新f[j] | 新g[j] | 变化说明 |
|---|---|---|---|---|---|
| 5 | 4 | 1 | 8 | 1 | 选择物品3(4+4=8>4),从g[2]继承方案数1 |
| 4 | 6 | 2 | 选择物品3(0+4=4<4),但j=4时选物品3实际是f[1]+4=2+4=6>4?等待,这里需要修正 |
修正计算过程: 对于j=4,选择物品3:需要查看j=4-3=1的状态
- f[1] = 2, 选择物品3后新价值 = 2+4 = 6
- 原f[4] = 4, 6>4,所以更新f[4]=6, g[4]=g[1]=1
| 容量 j | 原f[j] | 原g[j] | 新f[j] | 新g[j] | 变化说明 |
|---|---|---|---|---|---|
| 5 | 4 | 1 | 8 | 1 | 选择物品3(f[2]=4+4=8>4),从g[2]继承方案数1 |
| 4 | 6 | 选择物品3(f[1]=2+4=6>4),从g[1]继承方案数1 | |||
| 3 | 4 | 选择物品3(f[0]=0+4=4=4),方案数累加:1+1=2 | |||
| 2 | 不选物品3,保持不变 | ||||
| 1 | 2 | 2 | |||
| 0 | 0 | 保持不变 | |||
处理物品4 (体积=4, 价值=6)
| 容量 j | 原f[j] | 原g[j] | 新f[j] | 新g[j] | 变化说明 |
|---|---|---|---|---|---|
| 5 | 8 | 1 | 8 | 2 | 选择物品4(f[1]=2+6=8=8),方案数累加:1+1=2 |
| 4 | 6 | 6 | 选择物品4(f[0]=0+6=6=6),方案数累加:1+1=2 | ||
| 3 | 4 | 2 | 4 | 不选物品4,保持不变 | |
| 2 | 1 | 1 | |||
| 1 | 2 | 2 | |||
| 0 | 0 | 保持不变 | |||
最终结果
- 最大价值 f[5] = 8
- 方案数 g[5] = 2
两种达到最大价值8的方案:
- 物品2 + 物品3:体积2+3=5,价值4+4=8
- 物品1 + 物品4:体积1+4=5,价值2+6=8
1 条评论
-
liwenxuan AK-CSP MOD @ 2025-11-22 21:08:36太好了!
- 1