长跳跃
- 难度 入门
- 时限 1s
- 空限 256m
- 线性DP
数据规模:,所有测试用例的 之和不超过 ,。
思路
倒序 DP。 设 表示从第 个格子出发能获得的总分。从 起跳必然获得 分,落点是 :
- 若 ,落到格子 后还能继续跳,;
- 若 ,训练立即结束,但本次跳跃的 分照拿,。
转移只依赖下标更大的状态,所以从 到 倒序计算即可保证无后效性。由于 ,每个 的转移目标唯一,整张图是一组互不相交的链,倒序一遍就能扫完。答案为 。
复杂度
时间 ,额外空间 。
仓颉实现
查看仓颉实现
import std.env.*
import std.convert.*
func solve(reader: ConsoleReader): Unit {
let n = Int64.parse(reader.readln().getOrThrow())
let nn = n
let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({
p: String => Int64.parse(p)
})
let dp = Array<Int64>(nn + 1, { _ => 0 })
var best: Int64 = 0
var i: Int64 = nn
while (i >= 1) {
var v = a[i - 1]
let j = i + a[i - 1]
if (j <= nn) {
v += dp[j]
}
dp[i] = v
if (v > best) {
best = v
}
i -= 1
}
println(best)
}
main() {
let reader = getStdIn()
let t = Int64.parse(reader.readln().getOrThrow())
var k: Int64 = 0
while (k < t) {
solve(reader)
k += 1
}
}