数字消除游戏
- 难度 普及−
- 时限 1s
- 空限 256m
- 线性DP
数据规模:,。
思路
数值相同的整数同生共死。 选 会移除所有数值为 的整数;不选 ,它们最终也只能被 或 连带移除,自己不会产生任何得分。所以对每个数值 只有两种结局:取走(得分 ,代价是 和 都不能再取)或放弃(得分 )。
按值域从小到大做 线性 DP。设 表示取走数值 的总得分, 表示只考虑数值不超过 时的最大分数,则
即在「不取 」与「取 且 不取」二者中取大——这正是「不能选相邻项」的经典模型。 只与前两项有关,滚动两个变量即可,无需 DP 数组。
答案为遍历完值域后的 。样例中 、、,有 、、。
复杂度
时间 ,空间 。
仓颉实现
查看仓颉实现
import std.env.*
import std.convert.*
main() {
let reader = getStdIn()
let n = Int64.parse(reader.readln().getOrThrow())
let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let m: Int64 = 200002
let sum = Array<Int64>(m, { _ => 0 })
for (x in a) {
sum[x] += x
}
var prev: Int64 = 0
var cur: Int64 = 0
var v: Int64 = 1
while (v < m) {
var nxt = prev + sum[v]
if (cur > nxt) {
nxt = cur
}
prev = cur
cur = nxt
v += 1
}
println(cur)
}