Skip to content

Commit b709054

Browse files
committed
acwing: add 3_complete_knapsack_backpack_problem.go
1 parent 336877f commit b709054

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package __dynamic_programming
2+
3+
/**
4+
@author: CodeWater
5+
@since: 2025/03/03
6+
@desc: 完全背包问题
7+
和01背包非常类似,但是物品有无限个,所以集合划分按照每个物品选择了多少个来;由于物品是有重量,背包有容量,
8+
所以不能无限选择,假设选择到k个。
9+
这样就把f[i][j]分成了k类, 第一个部分是第i个物品选了0个的选法、 第二个部分是第i个物品选了1个的选法、 第三个部分是第i个物品选了2个的选法...。
10+
然后看每个部分该如何算。
11+
- 0个: 当前不选,等于上一层选择的情况。f[i - 1][j]
12+
- 1个往后的状态: 跟01背包分析一样,当前状态由之前的状态的推算而来,所以可以先减去k个物品然后加回来k个物品。 f[i - 1][j - k * v[i]] + k * w[i]
13+
当k = 0时,其实就是0个的表达式。所以这两个状态的表达式可以合并为第二个表达式。
14+
**/
15+
16+
import (
17+
"fmt"
18+
)
19+
20+
const N = 1010
21+
22+
var (
23+
// n中物品,背包容量为m
24+
n, m int
25+
v, w [N]int
26+
f [N][N]int
27+
)
28+
29+
func max(a, b int) int {
30+
if a > b {
31+
return a
32+
}
33+
return b
34+
}
35+
36+
func main() {
37+
fmt.Scan(&n, &m)
38+
for i := 1; i <= n; i++ {
39+
fmt.Scan(&v[i], &w[i])
40+
}
41+
42+
for i := 1; i <= n; i++ {
43+
for j := 0; j <= m; j++ {
44+
for k := 0; k*v[i] <= j; k++ {
45+
f[i][j] = max(f[i][j], f[i-1][j-k*v[i]]+k*w[i])
46+
}
47+
}
48+
}
49+
50+
fmt.Println(f[n][m])
51+
}

0 commit comments

Comments
 (0)