青蛙跳石头 2
- 难度 入门
- 时限 1s
- 空限 256m
- 线性DP
数据规模:,,。
思路
设 表示青蛙到达第 块石头的最少体力,。
考虑最后一次跳跃:青蛙从第 块石头跳到第 块石头,必须满足 ,代价为 。于是转移方程为
答案即 。
由于 ,每个状态只需检查至多 个前驱,直接枚举个数即可,无需单调队列等优化。注意代价与下标无关(只与高度差有关),所以窗口就是「下标距离不超过 」的连续区间,逐个取最小值即为最优。
复杂度
时间 次运算,空间 。
仓颉实现
查看仓颉实现
import std.env.*
import std.convert.*
import std.math.*
main() {
let reader = getStdIn()
let nk = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let n = nk[0]
let k = nk[1]
let h = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let nn = n
let kk = k
var dp = Array<Int64>(nn, { _ => 0 })
var i: Int64 = 1
while (i < nn) {
var best: Int64 = Int64.Max
var j: Int64 = if (i - kk > 0) { i - kk } else { 0 }
while (j < i) {
let c = dp[j] + abs(h[i] - h[j])
if (c < best) {
best = c
}
j += 1
}
dp[i] = best
i += 1
}
println(dp[nn - 1])
}