Skip to content

Commit

Permalink
add links and codes
Browse files Browse the repository at this point in the history
  • Loading branch information
EndlessCheng committed Apr 26, 2020
1 parent aab680a commit c47fe18
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 12 deletions.
16 changes: 10 additions & 6 deletions copypasta/dp.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,11 @@ func dpCollections() {
// https://en.wikipedia.org/wiki/Travelling_salesman_problem
// 模板题 https://www.luogu.com.cn/problem/P1171 https://www.luogu.com.cn/problem/P1433
// 建模转换题 https://leetcode-cn.com/problems/find-the-shortest-superstring/
// https://leetcode-cn.com/problems/xun-bao/
// EXTRA: 固定起点终点的问题,视问题情况有两种方法:
// 添加一个节点 https://stackoverflow.com/questions/14527815/how-to-fix-the-start-and-end-points-in-travelling-salesmen-problem
// 设置距离 https://stackoverflow.com/questions/36086406/traveling-salesman-tsp-with-set-start-and-end-point
tsp := func(dist [][]int) int {
tsp := func(dist [][]int, st int) int {
n := len(dist)
const inf int = 1e9
dp := make([][]int, 1<<n)
Expand All @@ -383,9 +384,9 @@ func dpCollections() {
return *dv
}
defer func() { *dv = res }()
if s == 1<<n-1 && v == 0 {
if s == 1<<n-1 && v == st {
return
} // 访问了所有节点并回到了 0
} // 访问了所有节点并回到了 st
res = inf
for w := 0; w < n; w++ {
if s>>w&1 == 0 {
Expand All @@ -394,7 +395,7 @@ func dpCollections() {
}
return
}
f(0, 0)
f(0, st)

// DP
dp = make([][]int, 1<<n)
Expand All @@ -404,7 +405,7 @@ func dpCollections() {
dp[i][j] = inf
}
}
dp[1<<n-1][0] = 0
dp[1<<n-1][st] = 0 // 访问了所有节点并回到了 st(多个起点的话就设置多个 dp[1<<n-1][st[i]] = 0
for s := 1<<n - 2; s >= 0; s-- {
for v := 0; v < n; v++ {
for w := 0; w < n; w++ {
Expand All @@ -414,7 +415,10 @@ func dpCollections() {
}
}
}
return dp[0][0]

// NOTE: dp[0][i] 表示从 st 出发,访问完所有位置最后在 i 的最短路径和

return dp[0][st]
}

/* 数位 DP
Expand Down
89 changes: 83 additions & 6 deletions copypasta/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ func searchCollection() {
// DFS 格点找有多少个连通分量
// 下列代码来自 LC162C https://leetcode-cn.com/problems/number-of-closed-islands/
// NOTE: 对于搜索格子的题,可以不用创建 vis 而是通过修改格子的值为范围外的值(如零、负数、'#' 等)来做到这一点
dfsGrids := func(grid [][]int) (comps int) {
dfsGrids := func(g [][]byte) (comps int) {
dir4 := [...][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} // 上下左右
n, m := len(grid), len(grid[0])
n, m := len(g), len(g[0])
vis := make([][]bool, n)
for i := range vis {
vis[i] = make([]bool, m)
Expand All @@ -19,7 +19,7 @@ func searchCollection() {
if i < 0 || i >= n || j < 0 || j >= m {
return false
}
if vis[i][j] || grid[i][j] != 0 {
if vis[i][j] || g[i][j] != 0 {
return true
}
vis[i][j] = true
Expand All @@ -32,7 +32,7 @@ func searchCollection() {
}
return validComp
}
for i, gi := range grid {
for i, gi := range g {
for j, gij := range gi {
if gij == 0 && !vis[i][j] && f(i, j) {
comps++
Expand All @@ -42,6 +42,83 @@ func searchCollection() {
return
}

type point struct{ x, y int }

findOneTargetAnyWhere := func(g [][]byte, tar byte) point {
for i, row := range g {
for j, b := range row {
if b == tar {
return point{i, j}
}
}
}
return point{-1, -1}
}

countTargetAnyWhere := func(g [][]byte, tar byte) (cnt int) {
for _, row := range g {
for _, b := range row {
if b == tar {
cnt++
}
}
}
return
}

type pair struct {
point
dep int
}

// 网格图从 (s.x,s.y) 到 (t.x,t.y) 的最短距离,'#' 为障碍物
// 无法到达时返回 -1
dir4 := [...][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} // 上下左右
bfsDis := func(g [][]byte, s, t point) int {
n, m := len(g), len(g[0])
vis := make([][]bool, n)
for i := range vis {
vis[i] = make([]bool, m)
}
vis[s.x][s.y] = true
for q := []pair{{s, 0}}; len(q) > 0; {
p := q[0]
q = q[1:]
if p.point == t {
return p.dep
}
for _, d := range dir4 {
if xx, yy := p.x+d[0], p.y+d[1]; xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && g[xx][yy] != '#' {
vis[xx][yy] = true
q = append(q, pair{point{xx, yy}, p.dep + 1})
}
}
}
return -1
}
findAllReachableTargets := func(g [][]byte, s point, tar byte) (ps []point) {
n, m := len(g), len(g[0])
vis := make([][]bool, n)
for i := range vis {
vis[i] = make([]bool, m)
}
vis[s.x][s.y] = true
for q := []point{s}; len(q) > 0; {
p := q[0]
q = q[1:]
if g[p.x][p.y] == tar {
ps = append(ps, p)
}
for _, d := range dir4 {
if xx, yy := p.x+d[0], p.y+d[1]; xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && g[xx][yy] != '#' {
vis[xx][yy] = true
q = append(q, point{xx, yy})
}
}
}
return
}

// 生成字符串 s 的所有长度至多为 r 的非空子串
// https://codeforces.ml/problemset/problem/120/H
genSubStrings := func(s string, r int) []string {
Expand Down Expand Up @@ -193,7 +270,7 @@ func searchCollection() {
// TODO: https://oi-wiki.org/search/dlx/

_ = []interface{}{
dfsPermutations, dfsGrids,
genSubStrings, combinations, permutations, permuteAll,
dfsGrids, findOneTargetAnyWhere, countTargetAnyWhere, bfsDis, findAllReachableTargets,
genSubStrings, dfsPermutations, combinations, permutations, permuteAll,
}
}

0 comments on commit c47fe18

Please sign in to comment.