[R40D] Yet another ICPC problem
- 难度 普及/提高-
- 时限 1s
- 空限 512m
- 排序前缀和
数据规模:,。
思路
假设 apiadu 解决 道题,jiangly 解决 道题。两人各自解题时疲劳值递增,且序列固定:apiadu 的第 题()附加 ,jiangly 的第 题附加 。因此疲劳值部分的总代价固定为
与题目分配无关,只需再最小化 ,其中 是分给 apiadu 的 道题。变形:
是常数,所以固定 时,把 最小的 道题分给 apiadu 即可。
实现上,将 排序后做前缀和 (前 个最小差值之和),并预处理 、 的前缀和 、 以及 ,枚举 取最小值:
复杂度:时间 (排序主导),空间 。
仓颉实现
import std.convert.*
import std.env.*
import std.sort.*
main(): Int64 {
let reader = getStdIn()
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 b = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let c = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let d = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
// diff[i] = a_i - b_i;sumB 为所有 b_i 之和
var sumB: Int64 = 0
let diff = Array<Int64>(nn, { _ => 0 })
for (i in 0..nn) {
sumB += b[i]
diff[i] = a[i] - b[i]
}
// pc[k] = c_0 + ... + c_{k-1},pd[k] = d_0 + ... + d_{k-1}
let pc = Array<Int64>(nn + 1, { _ => 0 })
for (i in 0..nn) {
pc[i + 1] = pc[i] + c[i]
}
let pd = Array<Int64>(nn + 1, { _ => 0 })
for (i in 0..nn) {
pd[i + 1] = pd[i] + d[i]
}
// diff 升序后 pref[k] = 最小的 k 个 a_i - b_i 之和
sort(diff)
let pref = Array<Int64>(nn + 1, { _ => 0 })
for (i in 0..nn) {
pref[i + 1] = pref[i] + diff[i]
}
// 枚举 apiadu 解题数 k
var ans: Int64 = pd[nn] + sumB
for (k in 1..nn + 1) {
let cur = pc[k] + pd[nn - k] + sumB + pref[k]
if (cur < ans) {
ans = cur
}
}
println(ans)
return 0
}