File tree Expand file tree Collapse file tree
algorithm/src/acwing/algorithmBasicCourse/5_dynamic_programming Expand file tree Collapse file tree Original file line number Diff line number Diff line change 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+ }
You can’t perform that action at this time.
0 commit comments