AT2287 [ARC067B] Walk and Teleport 题解
Content
一条直线上有 \(n\) 个城市,第 \(i\) 个城市的坐标为 \(x_i\)。你在某一个城市内,每一次你可以按两种方式之一进行移动:
- 左右移动,每移动一个单位疲劳值增加 \(a\)。
- 瞬移到某一个坐标,疲劳值增加 \(b\)。
求出去过所有的城市的最小疲劳值。
数据范围:\(2\leqslant n\leqslant 10^5,1\leqslant x_i,a,b\leqslant 10^9,x_i\leqslant x_{i+1}\)。
Solution
简单的模拟。
我们可以想到,如果你在某一个城市内但没有具体指定哪一个城市,那么最优的方案明显是选择最左边或者最右边的城市,然后逐次前往每个城市。这里以选择最左边的城市为例。
再想,我们如果直接在第 \(i\) 个城市和第 \(i+1\) 个城市之间左右移动,需要消耗的疲劳值肯定是 \(a\times(x_{i+1}-x_i)\),瞬移的话疲劳值是 \(b\),那么要疲劳值最小的话肯定取其最小值。所以,答案就是 \(\sum\limits_{i=1}^{n-1}\max(a\times(x_{i+1}-x_i),b)\)。
这篇在 NOIP2020 之前写下的最后一篇文章,也许是我的绝笔了吧。(然而并不是——笔者注于 2021 年 12 月 16 日)
Code
int n, a, pl[100007];
long long ans, b;
int main() {
n = Rint, a = Rint, b = Rll;
F(i, 1, n) pl[i] = Rint;
F(i, 1, n - 1) {
int dis = pl[i + 1] - pl[i];
ans += min(1ll * dis * a, b);
}
printf("%lld\n", ans);
return 0;
}