题目:
leetcode.cn/problems/so…
算法:
方法一:动态规划
func mostPoints(questions [][]int) int64 {
n := len(questions)
// dp[i]表示[0:i-1)区间的最大得分
dp := make([]int, n + 1)
for i := range questions {
dp[i + 1] = max(dp[i + 1], dp[i])
next := i + questions[i][1] + 1
if next >= n {
next = n
}
dp[next] = max(dp[next], dp[i] + questions[i][0])
}
return int64(dp[n])
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
方法二: 记忆化+暴力搜索
dfs暴力搜索不行是吧,ok,加上记忆化
func mostPoints(questions [][]int) int64 {
n := len(questions)
cache := make([]int, n)
var dfs func(i int) int
dfs = func(i int) int {
if i >= n {
return 0
}
if cache[i] > 0 {
return cache[i]
}
// 选当前课程
s := questions[i][0] + dfs(i + questions[i][1] + 1)
// 不选当前课程
ns := dfs(i + 1)
cache[i] = max(s, ns)
return cache[i]
}
return int64(dfs(0))
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
方法二:记忆化搜索的DP写法
func mostPoints(questions [][]int) int64 {
n := len(questions)
// var dfs func(i int) int
// dfs = func(i int) int {
// if i >= n {
// return 0
// }
// if cache[i] > 0 {
// return cache[i]
// }
// // 选当前课程
// s := questions[i][0] + dfs(i + questions[i][1] + 1)
// // 不选当前课程
// ns := dfs(i + 1)
// cache[i] = max(s, ns)
// return cache[i]
// }
// return int64(dfs(0))
dp := make([]int, n + 1)
for i := n - 1; i >= 0; i-- {
// 选当前的课程
j := i + questions[i][1] + 1
if j < n {
dp[i] = max(dp[i], questions[i][0] + dp[j])
} else {
dp[i] = questions[i][0]
}
// 不选当前的课程
dp[i] = max(dp[i], dp[i + 1])
}
return int64(dp[0])
}
func max(a, b int) int {
if a > b {
return a
}
return b
}