Skip to content

Commit 85ba926

Browse files
committed
acwing: add second method 900_integer_partition.go
1 parent 356a995 commit 85ba926

File tree

1 file changed

+61
-6
lines changed

1 file changed

+61
-6
lines changed

algorithm/src/acwing/algorithmBasicCourse/5_dynamic_programming/900_integer_partition.go

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,78 @@ import (
1212
的有多少个。
1313
*/
1414

15+
// const N, mod = 1010, 1e9 + 7
16+
17+
// var (
18+
// n int
19+
// // f[j]:是整数j的划分数量
20+
// f [N]int
21+
// )
22+
23+
// func main() {
24+
// fmt.Scan(&n)
25+
26+
// f[0] = 1
27+
// for i := 1; i <= n; i++ {
28+
// for j := i; j <= n; j++ {
29+
// f[j] = (f[j] + f[j-i]) % mod
30+
// }
31+
// }
32+
33+
// fmt.Println(f[n])
34+
// }
35+
36+
/*
37+
按照每个方案中最小的数是否大于1来划分状态,可以划分为两类:
38+
1. 最小值是1的
39+
2. 最小值严格大于1的
40+
*/
41+
1542
const N, mod = 1010, 1e9 + 7
1643

1744
var (
1845
n int
19-
// f[j]:是整数j的划分数量
20-
f [N]int
46+
// f[i][j]: 总和是i的,恰好用j个数表示的方案数
47+
f [N][N]int
2148
)
2249

2350
func main() {
2451
fmt.Scan(&n)
2552

26-
f[0] = 1
53+
// 初始状态,总和0用0个数表示的方案数有1个
54+
f[0][0] = 1
2755
for i := 1; i <= n; i++ {
28-
for j := i; j <= n; j++ {
29-
f[j] = (f[j] + f[j-i]) % mod
56+
for j := 1; j <= i; j++ {
57+
/*
58+
f[i][j]: 包含两种状态,方案数根据两种状态的上一步状态推算而来。
59+
1. 最小值是1的部分:这部分每个方案去掉一个1,每个方案总和是i-1,个数是j-1个,方案数
60+
不变。那么此时状态方程可以表示为f[i - 1][j - 1],也就是说f[i - 1][j - 1]和f[i][j]最
61+
小值是1的部分方案数一样。
62+
例如,对于总和为5,用3个数表示的方案中,包含数字1的有:
63+
- [1,1,3]
64+
- [1,2,2]
65+
如果从每个方案中移除一个1,就得到:
66+
- [1,3] (总和为4,用2个数)
67+
- [2,2] (总和为4,用2个数)
68+
这正好对应f[4][2],即f[i-1][j-1]。
69+
70+
2. 最小值大于1的部分: 这部分每个方案里面的每个数减掉一个1,每个方案总和变成i-j,但个数
71+
不变。此时状态方程f[i-j][j],也就是对应f[i][j]最小值大于1的部分的方案数。
72+
例如,对于总和为7,用3个数表示且所有数字都大于1的方案:
73+
- [2,2,3]
74+
如果从每个数字中都减去1,就得到:
75+
- [1,1,2] (总和为4,仍然用3个数)
76+
这对应于f[4][3],即f[i-j][j]。
77+
78+
注意两个部分的方程反向推断的意思。
79+
*/
80+
f[i][j] = (f[i-1][j-1] + f[i-j][j]) % mod
3081
}
3182
}
3283

33-
fmt.Println(f[n])
84+
res := 0
85+
for i := 1; i <= n; i++ {
86+
res = (res + f[n][i]) % mod
87+
}
88+
fmt.Println(res)
3489
}

0 commit comments

Comments
 (0)