Skip to content

Commit befc147

Browse files
committed
add links
1 parent ccec4d6 commit befc147

File tree

1 file changed

+70
-47
lines changed

1 file changed

+70
-47
lines changed

copypasta/dp.go

+70-47
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ https://leetcode.cn/problems/shortest-common-supersequence/solution/cong-di-gui-
2222
2323
前缀/后缀之间的转移,例如从 f[i-1] 转移到 f[i],或者从 f[j] 转移到 f[i]
2424
LC70 爬楼梯 https://leetcode.cn/problems/climbing-stairs/
25-
- 变形:有花费 LC746 https://leetcode.cn/problems/min-cost-climbing-stairs/
25+
- 有花费 LC746 https://leetcode.cn/problems/min-cost-climbing-stairs/
2626
- https://atcoder.jp/contests/dp/tasks/dp_a
2727
- https://atcoder.jp/contests/dp/tasks/dp_b
28-
- 变形:有障碍物 https://atcoder.jp/contests/abc129/tasks/abc129_c
28+
- 有障碍物 https://atcoder.jp/contests/abc129/tasks/abc129_c
2929
LC198 打家劫舍 https://leetcode.cn/problems/house-robber/
30-
- 变形:值域打家劫舍 LC740 https://leetcode.cn/problems/delete-and-earn/
31-
- 变形:恰好选 floor(n/2) 个 https://atcoder.jp/contests/abc162/tasks/abc162_f
32-
- 变形:矩阵打家劫舍 https://codeforces.com/problemset/problem/1195/C
30+
- 值域打家劫舍 LC740 https://leetcode.cn/problems/delete-and-earn/
31+
- 分组+值域打家劫舍 https://atcoder.jp/contests/abc403/tasks/abc403_d
32+
- 恰好选 floor(n/2) 个 https://atcoder.jp/contests/abc162/tasks/abc162_f
33+
- 矩阵打家劫舍 https://codeforces.com/problemset/problem/1195/C
3334
- 环形 LC213 https://leetcode.cn/problems/house-robber-ii/
3435
- 环形 https://atcoder.jp/contests/abc251/tasks/abc251_e
3536
LC2369 https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/ 1780
@@ -61,6 +62,7 @@ https://codeforces.com/problemset/problem/1920/E 2000
6162
https://codeforces.com/problemset/problem/2027/D2 2200 在 DP 数组上滑窗
6263
https://codeforces.com/problemset/problem/2045/H 2200
6364
https://codeforces.com/problemset/problem/6/D 2600
65+
https://atcoder.jp/contests/dp/tasks/dp_t 状态设计
6466
https://www.luogu.com.cn/problem/P2258
6567
6668
输出具体方案
@@ -117,6 +119,8 @@ https://codeforces.com/contest/2043/problem/C
117119
118120
网格路径问题 网格图 DP
119121
技巧:对于求方案数的题目,可以初始化 f[0][1] = 1,从而避免单独讨论左上角 f[1][1] 的计算
122+
- [63. 不同路径 II](https://leetcode.cn/problems/unique-paths-ii/)
123+
- https://atcoder.jp/contests/dp/tasks/dp_h
120124
- [64. 最小路径和](https://leetcode.cn/problems/minimum-path-sum/)
121125
- 变形:连续性 & 上下界思想 https://codeforces.com/contest/1695/problem/C
122126
- https://atcoder.jp/contests/arc137/tasks/arc137_b 也用到了这个思想
@@ -1291,7 +1295,8 @@ func _(abs func(int) int) {
12911295
// - 变形,需要多加一个维度 https://atcoder.jp/contests/abc275/tasks/abc275_f
12921296
// https://atcoder.jp/contests/abc159/tasks/abc159_f 贡献
12931297
// https://atcoder.jp/contests/agc020/tasks/agc020_c 所有非空子集和的中位数
1294-
// NOIP06·提高 金明的预算方案(也可以用树上背包做)https://www.luogu.com.cn/problem/P1064
1298+
// https://atcoder.jp/contests/dp/tasks/dp_x 邻项交换法
1299+
// https://www.luogu.com.cn/problem/P1064 NOIP06·提高 金明的预算方案(也可以用树上背包做)
12951300
// EXTRA: 恰好装满(相当于方案数不为 0)LC416 https://leetcode.cn/problems/partition-equal-subset-sum/
12961301
// 必须定义成恰好装满(紫书例题 9-5,UVa 12563)https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=441&page=show_problem&problem=4008
12971302
// EXTRA: 背包容量为 0 https://codeforces.com/problemset/problem/366/C 1900
@@ -1583,12 +1588,13 @@ func _(abs func(int) int) {
15831588
// 每个物品的体积都是 1
15841589
// 如果题目要求每种物品至少选一个,可以把每个 cnts[i] 都减一,maxW 减去 len(cnts),这样就转换成了每种物品至少选 0 个的情况了
15851590
// 讲解 https://leetcode.cn/problems/find-the-original-typed-string-ii/solutions/2966856/zheng-nan-ze-fan-qian-zhui-he-you-hua-dp-5mi9/
1591+
// https://atcoder.jp/contests/dp/tasks/dp_m
15861592
// 挑战 pp.68-69 多重集组合数
15871593
// 另见 math_comb.go 中的「多重集组合数」容斥做法
15881594
// https://codeforces.com/problemset/problem/156/C 也可以用容斥
15891595
boundedKnapsackWays := func(cnts []int, maxW int) int {
15901596
// 从 len(cnts) 种物品中选出【至多】maxW 个物品的方案数
1591-
// f[i+1][j] 表示从前 i 种物品中选恰好 j 个物品的方案数(第一维度优化掉
1597+
// f[i+1][j] 表示从前 i 种物品中选【恰好】j 个物品的方案数(优化掉第一个维度
15921598
f := make([]int, maxW+1)
15931599
f[0] = 1
15941600
for _, c := range cnts {
@@ -2128,6 +2134,8 @@ func _(abs func(int) int) {
21282134
σ²(x) = sum(x²)/n - (sum(x)/n)²
21292135
21302136
概率 DP
2137+
https://atcoder.jp/contests/dp/tasks/dp_i 入门题
2138+
- 在本题中,选或不选不是人为决定的,而是由概率决定的
21312139
https://codeforces.com/problemset/problem/16/E 1900
21322140
https://codeforces.com/problemset/problem/540/D 1900
21332141
https://codeforces.com/problemset/problem/678/E 2200
@@ -2143,7 +2151,7 @@ func _(abs func(int) int) {
21432151
https://www.luogu.com.cn/problem/P2719 用组合数学做
21442152
21452153
期望 DP
2146-
入门题 https://atcoder.jp/contests/abc280/tasks/abc280_e
2154+
https://atcoder.jp/contests/abc280/tasks/abc280_e 入门题
21472155
https://atcoder.jp/contests/abc350/tasks/abc350_e
21482156
- 如果状态转移左右两边都包含 f[i],则需要移项化简
21492157
https://atcoder.jp/contests/dp/tasks/dp_j
@@ -2305,6 +2313,7 @@ func _(abs func(int) int) {
23052313
// https://codeforces.com/problemset/problem/1598/F 2400 合法括号字符串
23062314
// https://codeforces.com/problemset/problem/1550/E 2500 状态设计
23072315
// https://www.luogu.com.cn/problem/P3694 前缀和
2316+
// LC3530 https://leetcode.cn/problems/maximum-profit-from-valid-topological-order-in-dag/ DAG 排列
23082317
permDP := func(a []int, check func(int, int) bool) int {
23092318
n := len(a)
23102319
f := make([]int, 1<<n)
@@ -2961,30 +2970,32 @@ func _(abs func(int) int) {
29612970
}
29622971

29632972
//(旧版写法)做两次记忆化搜索(或者题目只需要考虑上界)
2964-
digitDP2 := func(low, high string, sumUpper int) int {
2965-
// 返回 <=s 的符合要求的字符串数目
2966-
// TIPS: 某些情况下思考补集会更加容易,即求不符合要求的字符串数目
2973+
digitDP2 := func(low, high string, k int) int {
29672974
calc := func(s string) int {
2968-
// 注:如果参数太多可以用 map + struct
2975+
// 注:如果参数太多可以用 map
29692976
memo := make([][]int, len(s))
29702977
for i := range memo {
2971-
memo[i] = make([]int, sumUpper+1)
2978+
memo[i] = make([]int, k)
29722979
for j := range memo[i] {
29732980
memo[i][j] = -1
29742981
}
29752982
}
29762983

29772984
// 第一种写法(前导零不影响答案)
29782985
var f func(int, int, bool) int
2979-
f = func(i int, sum int, isLimit bool) (res int) {
2986+
f = func(i, sum int, isLimit bool) (res int) {
29802987
if i == len(s) {
2988+
if sum > 0 {
2989+
return
2990+
}
29812991
return 1
2982-
} // sum
2992+
}
29832993
if !isLimit {
29842994
dv := &memo[i][sum]
29852995
if *dv >= 0 {
29862996
return *dv
2987-
} // *dv + sum*int(math.Pow10(len(s)-i))
2997+
}
2998+
// *dv + sum*int(math.Pow10(len(s)-i))
29882999
defer func() { *dv = res }()
29893000
}
29903001

@@ -2993,12 +3004,10 @@ func _(abs func(int) int) {
29933004
up = int(s[i] - '0') // 'a'
29943005
}
29953006

2996-
for d := 0; d <= up; d++ {
2997-
tmp := sum
2998-
2999-
cnt := f(i+1, tmp, isLimit && d == up)
3000-
res = (res + cnt) % mod
3007+
for d := range up + 1 {
3008+
res += f(i+1, (sum+d)%k, isLimit && d == up)
30013009
}
3010+
res %= mod
30023011
return
30033012
}
30043013
//res := f(0, 0, true)
@@ -3224,46 +3233,54 @@ func _(abs func(int) int) {
32243233
return
32253234
}
32263235

3227-
/* 倍增优化 DP
3228-
https://codeforces.com/problemset/problem/1175/E 模板题
3236+
/* 倍增
3237+
https://oi-wiki.org/basic/binary-lifting/
3238+
https://atcoder.jp/contests/arc060/tasks/arc060_c 模板题
3239+
- LC3534 https://leetcode.cn/problems/path-existence-queries-in-a-graph-ii/ 重新编号(下标映射)
3240+
https://codeforces.com/problemset/problem/1175/E
32293241
https://codeforces.com/problemset/problem/1516/D
3230-
https://atcoder.jp/contests/arc060/tasks/arc060_c
32313242
https://www.luogu.com.cn/problem/P1081 开车旅行
32323243
https://www.luogu.com.cn/problem/P3147 合并数字
32333244
https://www.luogu.com.cn/problem/P1613
3234-
计算重复 https://www.acwing.com/problem/content/296/
3245+
https://www.acwing.com/problem/content/296/ 计算重复
32353246
*/
3236-
binaryLifting := func(segs, qs []struct{ l, r int }) []int {
3237-
// 以 CF1175E 为例
3238-
const mx = 19
3239-
f := make([][mx]int, 5e5+1)
3240-
for _, s := range segs {
3241-
l, r := s.l, s.r
3242-
f[l][0] = max(f[l][0], r)
3243-
}
3244-
// 前缀最大值(最右)
3245-
for i := 1; i < len(f); i++ {
3246-
f[i][0] = max(f[i][0], f[i-1][0])
3247+
binaryLifting := func(left []int, qs []struct{ l, r int }) []int {
3248+
// 以 https://atcoder.jp/contests/arc060/tasks/arc060_c + https://leetcode.cn/problems/path-existence-queries-in-a-graph-ii/ 为例
3249+
n := len(left)
3250+
const mx = 17 // bits.Len(uint(n))
3251+
pa := make([][mx]int, n)
3252+
for i, l := range left {
3253+
pa[i][0] = l
32473254
}
3248-
// 倍增
3249-
for i := 0; i+1 < mx; i++ {
3250-
for p := range f {
3251-
f[p][i+1] = f[f[p][i]][i]
3255+
for i := range mx - 1 {
3256+
for x := range pa {
3257+
p := pa[x][i]
3258+
pa[x][i+1] = pa[p][i]
32523259
}
32533260
}
32543261

32553262
ans := make([]int, len(qs))
32563263
for qi, q := range qs {
32573264
l, r := q.l, q.r
3265+
if l == r {
3266+
// ans[qi] = 0
3267+
continue
3268+
}
3269+
if l > r {
3270+
l, r = r, l
3271+
}
32583272
res := 0
3259-
for i := mx - 1; i >= 0; i-- {
3260-
if f[l][i] < r {
3261-
l = f[l][i]
3262-
res |= 1 << i
3273+
for k := mx - 1; k >= 0; k-- {
3274+
p := pa[r][k]
3275+
if p > l {
3276+
res |= 1 << k
3277+
r = p
32633278
}
32643279
}
3265-
if f[l][0] >= r {
3266-
ans[qi] = res + 1
3280+
res++
3281+
r = pa[r][0]
3282+
if r <= l {
3283+
ans[qi] = res
32673284
} else {
32683285
ans[qi] = -1
32693286
}
@@ -3277,7 +3294,8 @@ func _(abs func(int) int) {
32773294
LC2713 https://leetcode.cn/problems/maximum-strictly-increasing-cells-in-a-matrix/
32783295
线段树 LC2407 https://leetcode.cn/problems/longest-increasing-subsequence-ii/ 2280
32793296
变量优化 O(n) LC2746 https://leetcode.cn/problems/decremental-string-concatenation/
3280-
https://atcoder.jp/contests/abc339/tasks/abc339_e 入门 值域线段树
3297+
https://atcoder.jp/contests/dp/tasks/dp_q 入门题 值域树状数组
3298+
https://atcoder.jp/contests/abc339/tasks/abc339_e 入门题 值域线段树
32813299
https://atcoder.jp/contests/dp/tasks/dp_w Lazy 线段树
32823300
https://atcoder.jp/contests/arc073/tasks/arc073_d
32833301
- https://www.luogu.com.cn/problem/T190609?contestId=48376
@@ -3316,9 +3334,12 @@ func _(abs func(int) int) {
33163334
https://codeforces.com/problemset/problem/46/E 1900 前缀最大值/后缀最大值
33173335
https://codeforces.com/problemset/problem/479/E 1900
33183336
- https://atcoder.jp/contests/abc253/tasks/abc253_e
3337+
https://atcoder.jp/contests/dp/tasks/dp_t 排列问题的状态设计
3338+
- 相似题目 https://leetcode.cn/problems/count-the-number-of-inversions/
33193339
https://atcoder.jp/contests/abc248/tasks/abc248_c
33203340
https://atcoder.jp/contests/diverta2019/tasks/diverta2019_e
33213341
https://codeforces.com/problemset/problem/708/E 3100
3342+
另见本页面的 boundedKnapsackWays(前缀和优化多重背包方案数)
33223343
33233344
其他
33243345
https://codeforces.com/problemset/problem/1863/F 2600
@@ -3638,6 +3659,7 @@ func _(abs func(int) int) {
36383659
https://codeforces.com/problemset/problem/1453/E 2300 好题
36393660
https://codeforces.com/problemset/problem/238/C 做到 O(n) ~2400
36403661
https://codeforces.com/problemset/problem/1059/E 2400 取往上冲的最高的点(子树)
3662+
https://atcoder.jp/contests/dp/tasks/dp_p
36413663
https://atcoder.jp/contests/abc259/tasks/abc259_f
36423664
https://atcoder.jp/contests/abc239/tasks/abc239_e
36433665
https://atcoder.jp/contests/abc207/tasks/abc207_f
@@ -4382,6 +4404,7 @@ func _(abs func(int) int) {
43824404
// 数位 DP
43834405
digitDP, digitDP2, calcSum, digitDP2D, kth666,
43844406

4407+
// 倍增
43854408
binaryLifting,
43864409

43874410
// 数据结构优化 DP

0 commit comments

Comments
 (0)