# 卿è§å
## èæ¯
å
ä»ä¸éé¢ç®å¼å§~
å¦é¢  [triangle](https://leetcode-cn.com/problems/triangle/)
> ç»å®ä¸ä¸ªä¸è§å½¢ï¼æ¾åºèªé¡¶åä¸çæå°è·¯å¾åãæ¯ä¸æ¥åªè½ç§»å¨å°ä¸ä¸è¡ä¸ç¸é»çç»ç¹ä¸ã
ä¾å¦ï¼ç»å®ä¸è§å½¢ï¼
```text
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
```
èªé¡¶åä¸çæå°è·¯å¾å为  11ï¼å³ï¼2 + 3 + 5 + 1 = 11ï¼ã
ä½¿ç¨ DFSï¼éå æè
åæ²»æ³ï¼
éå

åæ²»æ³

ä¼å DFSï¼ç¼åå·²ç»è¢«è®¡ç®çå¼ï¼ç§°ä¸ºï¼è®°å¿åæç´¢ æ¬è´¨ä¸ï¼å¨æè§åï¼

卿è§åå°±æ¯æå¤§é®é¢åæå°é®é¢ï¼å¹¶è§£å³äºå°é®é¢éå¤è®¡ç®çæ¹æ³ç§°ä¸ºå¨æè§å
卿è§åå DFS åºå«
- äºåæ åé®é¢æ¯æ²¡æäº¤éï¼æä»¥å¤§é¨åäºåæ é½ç¨é彿è
åæ²»æ³ï¼å³ DFSï¼å°±å¯ä»¥è§£å³
- å triangle è¿ç§æ¯æéå¤èµ°çæ
åµï¼**åé®é¢æ¯æäº¤é**ï¼æä»¥å¯ä»¥ç¨å¨æè§åæ¥è§£å³
卿è§åï¼èªåºåä¸
```go
func minimumTotal(triangle [][]int) int {
if len(triangle) == 0 || len(triangle[0]) == 0 {
return 0
}
// 1ãç¶æå®ä¹ï¼f[i][j] 表示ä»i,jåºåï¼å°è¾¾æåä¸å±çæçè·¯å¾
var l = len(triangle)
var f = make([][]int, l)
// 2ãåå§å
for i := 0; i < l; i++ {
for j := 0; j < len(triangle[i]); j++ {
if f[i] == nil {
f[i] = make([]int, len(triangle[i]))
}
f[i][j] = triangle[i][j]
}
}
// 3ã鿍æ±è§£
for i := len(triangle) - 2; i >= 0; i-- {
for j := 0; j < len(triangle[i]); j++ {
f[i][j] = min(f[i+1][j], f[i+1][j+1]) + triangle[i][j]
}
}
// 4ãçæ¡
return f[0][0]
}
func min(a, b int) int {
if a > b {
return b
}
return a
}
```
卿è§åï¼èªé¡¶åä¸
```go
// æµè¯ç¨ä¾ï¼
// [
// [2],
// [3,4],
// [6,5,7],
// [4,1,8,3]
// ]
func minimumTotal(triangle [][]int) int {
if len(triangle) == 0 || len(triangle[0]) == 0 {
return 0
}
// 1ãç¶æå®ä¹ï¼f[i][j] 表示ä»0,0åºåï¼å°è¾¾i,jçæçè·¯å¾
var l = len(triangle)
var f = make([][]int, l)
// 2ãåå§å
for i := 0; i < l; i++ {
for j := 0; j < len(triangle[i]); j++ {
if f[i] == nil {
f[i] = make([]int, len(triangle[i]))
}
f[i][j] = triangle[i][j]
}
}
// 鿍æ±è§£
for i := 1; i < l; i++ {
for j := 0; j < len(triangle[i]); j++ {
// è¿éåä¸ºä¸¤ç§æ
åµï¼
// 1ãä¸ä¸å±æ²¡æå·¦è¾¹å¼
// 2ãä¸ä¸å±æ²¡æå³è¾¹å¼
if j-1 < 0 {
f[i][j] = f[i-1][j] + triangle[i][j]
} else if j >= len(f[i-1]) {
f[i][j] = f[i-1][j-1] + triangle[i][j]
} else {
f[i][j] = min(f[i-1][j], f[i-1][j-1]) + triangle[i][j]
}
}
}
result := f[l-1][0]
for i := 1; i < len(f[l-1]); i++ {
result = min(result, f[l-1][i])
}
return result
}
func min(a, b int) int {
if a > b {
return b
}
return a
}
```
## éå½åå¨è§å
³ç³»
é彿¯ä¸ç§ç¨åºçå®ç°æ¹å¼ï¼å½æ°çèªæè°ç¨
```go
Function(x) {
...
Funciton(x-1);
...
}
```
卿è§åï¼æ¯ä¸ç§è§£å³é® é¢çææ³ï¼å¤§è§æ¨¡é®é¢çç»æï¼æ¯ç±å°è§æ¨¡é® é¢çç»æè¿ç®å¾æ¥çã卿è§åå¯ç¨é彿¥å®ç°(Memorization Search)
## 使ç¨åºæ¯
满足两个æ¡ä»¶
- æ»¡è¶³ä»¥ä¸æ¡ä»¶ä¹ä¸
- æ±æå¤§/æå°å¼ï¼Maximum/Minimum ï¼
- æ±æ¯å¦å¯è¡ï¼Yes/No ï¼
- æ±å¯è¡ä¸ªæ°ï¼Count(\*) ï¼
- 满足ä¸è½æåºæè
交æ¢ï¼Can not sort / swap ï¼
å¦é¢ï¼[longest-consecutive-sequence](https://leetcode-cn.com/problems/longest-consecutive-sequence/) ä½ç½®å¯ä»¥äº¤æ¢ï¼æä»¥ä¸ç¨å¨æè§å
## åç¹è¦ç´
1. **ç¶æ State**
- çµæï¼åé åï¼åå¨å°è§æ¨¡é®é¢çç»æ
2. æ¹ç¨ Function
- ç¶æä¹é´çèç³»ï¼æä¹éè¿å°çç¶æï¼æ¥ç®å¤§çç¶æ
3. åå§å Intialization
- ææéçå°ç¶ææ¯ä»ä¹, èµ·ç¹
4. çæ¡ Answer
- æå¤§çé£ä¸ªç¶ææ¯ä»ä¹ï¼ç»ç¹
## 常è§åç§ç±»å
1. Matrix DP (10%)
1. Sequence (40%)
1. Two Sequences DP (40%)
1. Backpack (10%)
> 注æç¹
>
> - è´ªå¿ç®æ³å¤§å¤é¢ç®é èçæ¡ï¼æä»¥å¦æè½ç¨å¨æè§å就尽éç¨å¨è§ï¼ä¸ç¨è´ªå¿ç®æ³
## 1ãç©éµç±»åï¼10%ï¼
### [minimum-path-sum](https://leetcode-cn.com/problems/minimum-path-sum/)
> ç»å®ä¸ä¸ªå
å«éè´æ´æ°ç  *m* x *n*Â ç½æ ¼ï¼è¯·æ¾åºä¸æ¡ä»å·¦ä¸è§å°å³ä¸è§çè·¯å¾ï¼ä½¿å¾è·¯å¾ä¸çæ°åæ»å为æå°ã
æè·¯ï¼å¨æè§å
1ãstate: f[x][y]ä»èµ·ç¹èµ°å° x,y çæçè·¯å¾
2ãfunction: f[x][y] = min(f[x-1][y], f[x][y-1]) + A[x][y]
3ãintialize: f[0][0] = A[0][0]ãf[i][0] = sum(0,0 -> i,0)ã f[0][i] = sum(0,0 -> 0,i)
4ãanswer: f[n-1][m-1]
```go
func minPathSum(grid [][]int) int {
// æè·¯ï¼å¨æè§å
// f[i][j] 表示i,jå°0,0çåæå°
if len(grid) == 0 || len(grid[0]) == 0 {
return 0
}
// å¤ç¨åæ¥çç©éµå表
// åå§åï¼f[i][0]ãf[0][j]
for i := 1; i < len(grid); i++ {
grid[i][0] = grid[i][0] + grid[i-1][0]
}
for j := 1; j < len(grid[0]); j++ {
grid[0][j] = grid[0][j] + grid[0][j-1]
}
for i := 1; i < len(grid); i++ {
for j := 1; j < len(grid[i]); j++ {
grid[i][j] = min(grid[i][j-1], grid[i-1][j]) + grid[i][j]
}
}
return grid[len(grid)-1][len(grid[0])-1]
}
func min(a, b int) int {
if a > b {
return b
}
return a
}
```
### [unique-paths](https://leetcode-cn.com/problems/unique-paths/)
> ä¸ä¸ªæºå¨äººä½äºä¸ä¸ª m x n ç½æ ¼çå·¦ä¸è§ ï¼èµ·å§ç¹å¨ä¸å¾ä¸æ 记为âStartâ ï¼ã
> æºå¨äººæ¯æ¬¡åªè½å䏿è
åå³ç§»å¨ä¸æ¥ãæºå¨äººè¯å¾è¾¾å°ç½æ ¼çå³ä¸è§ï¼å¨ä¸å¾ä¸æ 记为âFinishâï¼ã
> 鮿»å
±æå¤å°æ¡ä¸åçè·¯å¾ï¼
```go
func uniquePaths(m int, n int) int {
// f[i][j] 表示i,jå°0,0è·¯å¾æ°
f := make([][]int, m)
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if f[i] == nil {
f[i] = make([]int, n)
}
f[i][j] = 1
}
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
f[i][j] = f[i-1][j] + f[i][j-1]
}
}
return f[m-1][n-1]
}
```
### [unique-paths-ii](https://leetcode-cn.com/problems/unique-paths-ii/)
> ä¸ä¸ªæºå¨äººä½äºä¸ä¸ª m x n ç½æ ¼çå·¦ä¸è§ ï¼èµ·å§ç¹å¨ä¸å¾ä¸æ 记为âStartâ ï¼ã
> æºå¨äººæ¯æ¬¡åªè½å䏿è
åå³ç§»å¨ä¸æ¥ãæºå¨äººè¯å¾è¾¾å°ç½æ ¼çå³ä¸è§ï¼å¨ä¸å¾ä¸æ 记为âFinishâï¼ã
> 鮿»å
±æå¤å°æ¡ä¸åçè·¯å¾ï¼
> ç°å¨èèç½æ ¼ä¸æéç¢ç©ãé£ä¹ä»å·¦ä¸è§å°å³ä¸è§å°ä¼æå¤å°æ¡ä¸åçè·¯å¾ï¼
```go
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
// f[i][j] = f[i-1][j] + f[i][j-1] å¹¶æ£æ¥éç¢ç©
if obstacleGrid[0][0] == 1 {
return 0
}
m := len(obstacleGrid)
n := len(obstacleGrid[0])
f := make([][]int, m)
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if f[i] == nil {
f[i] = make([]int, n)
}
f[i][j] = 1
}
}
for i := 1; i < m; i++ {
if obstacleGrid[i][0] == 1 || f[i-1][0] == 0 {
f[i][0] = 0
}
}
for j := 1; j < n; j++ {
if obstacleGrid[0][j] == 1 || f[0][j-1] == 0 {
f[0][j] = 0
}
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
if obstacleGrid[i][j] == 1 {
f[i][j] = 0
} else {
f[i][j] = f[i-1][j] + f[i][j-1]
}
}
}
return f[m-1][n-1]
}
```
## 2ãåºåç±»åï¼40%ï¼
### [climbing-stairs](https://leetcode-cn.com/problems/climbing-stairs/)
> åè®¾ä½ æ£å¨ç¬æ¥¼æ¢¯ãéè¦ Â *n* é¶ä½ æè½å°è¾¾æ¥¼é¡¶ã
```go
func climbStairs(n int) int {
// f[i] = f[i-1] + f[i-2]
if n == 1 || n == 0 {
return n
}
f := make([]int, n+1)
f[1] = 1
f[2] = 2
for i := 3; i <= n; i++ {
f[i] = f[i-1] + f[i-2]
}
return f[n]
}
```
### [jump-game](https://leetcode-cn.com/problems/jump-game/)
> ç»å®ä¸ä¸ªéè´æ´æ°æ°ç»ï¼ä½ æåä½äºæ°ç»ç第ä¸ä¸ªä½ç½®ã
> æ°ç»ä¸çæ¯ä¸ªå
ç´ ä»£è¡¨ä½ å¨è¯¥ä½ç½®å¯ä»¥è·³è·çæå¤§é¿åº¦ã
> å¤æä½ æ¯å¦è½å¤å°è¾¾æåä¸ä¸ªä½ç½®ã
```go
func canJump(nums []int) bool {
// æè·¯ï¼çæåä¸è·³
// ç¶æï¼f[i] 表示æ¯å¦è½ä»0è·³å°i
// æ¨å¯¼ï¼f[i] = OR(f[j],j= i {
f[i] = true
}
}
}
return f[len(nums)-1]
}
```
### [jump-game-ii](https://leetcode-cn.com/problems/jump-game-ii/)
> ç»å®ä¸ä¸ªéè´æ´æ°æ°ç»ï¼ä½ æåä½äºæ°ç»ç第ä¸ä¸ªä½ç½®ã
> æ°ç»ä¸çæ¯ä¸ªå
ç´ ä»£è¡¨ä½ å¨è¯¥ä½ç½®å¯ä»¥è·³è·çæå¤§é¿åº¦ã
> ä½ çç®æ æ¯ä½¿ç¨æå°çè·³è·æ¬¡æ°å°è¾¾æ°ç»çæåä¸ä¸ªä½ç½®ã
```go
// v1卿è§åï¼å
¶ä»è¯è¨è¶
æ¶åèv2ï¼
func jump(nums []int) int {
// ç¶æï¼f[i] 表示ä»èµ·ç¹å°å½åä½ç½®æå°æ¬¡æ°
// æ¨å¯¼ï¼f[i] = f[j],a[j]+j >=i,min(f[j]+1)
// åå§åï¼f[0] = 0
// ç»æï¼f[n-1]
f := make([]int, len(nums))
f[0] = 0
for i := 1; i < len(nums); i++ {
// f[i] æå¤§å¼ä¸ºi
f[i] = i
// éåä¹åç»æåä¸ä¸ªæå°å¼+1
for j := 0; j < i; j++ {
if nums[j]+j >= i {
f[i] = min(f[j]+1,f[i])
}
}
}
return f[len(nums)-1]
}
func min(a, b int) int {
if a > b {
return b
}
return a
}
```
```go
// v2 卿è§å+è´ªå¿ä¼å
func jump(nums []int) int {
n:=len(nums)
f := make([]int, n)
f[0] = 0
for i := 1; i < n; i++ {
// å第ä¸ä¸ªè½è·³å°å½åä½ç½®çç¹å³å¯
// å ä¸ºè·³è·æ¬¡æ°çç»æéæ¯åè°éå¢çï¼æä»¥è´ªå¿æè·¯æ¯æ£ç¡®ç
idx:=0
for idx