题解 P5638 【【CSGRound2】光骓者的荣耀】
题解原因
这篇题解旨在帮助理解,dalao请忽视。
因为这是一道所以我在这里讲述的详细一点。
题目简介
有
但是小K可以从第
注意:他可以不访问所有的城市,使用传送器不耗费时间 (这句话意味着上面的跳转方案的思路是正确的,比如我完全可以从城市 1 跳到城市 4 ,只要使小K走过的总长度最短就可以)
求最快的用时 (即求最短的走路长度)。
思路分析
结合样例,我们可以发现,我们最终走过的长度就是
总长度使一个固定值,即所有路径的长度和。
那么要使得最终走过的长度最短,只需使跳转的长度最大。
我们只需要在所给的
我们可以枚举每一个
for (int i = 1; i <= n; i++) {
long long ans2 = 0;
for (int j = 0; j < k; j++) {
ans2 += cxk[i + j];
}
maxx = max(maxx, ans2);
}
但是我们会发现这个毒瘤数据范围(注意看21~25)
显然这样循环会重复计算中间的一些值,21~25都会超时。
那么我们怎么优化呢?
优化
我们可以在循环的基础上,去掉重复计算的值。
在从
a = 0, b = a + k;
for (int i = a; i < b; i++)
ans2 += cxk[i];
for (int i = 1; i <= n - k; i++) {
ans2 = ans2 + cxk[b] - cxk[a];
maxx = max(maxx, ans2);
a++, b++;
}
当然输出时应该输出总长度-跳转的长度,
cout << ans - maxx;
这就是核心代码了,最后把 头文件及初始化一写:
#include <bits/stdc++.h>
using namespace std;
int n, k, a, b;
long long cxk[1000010], ans, maxx, ans2;
数据读入:
ios::sync_with_stdio(false);
cin >> n >> k;
for (int i = 1; i <= n - 1; i++)
cin >> cxk[i], ans += cxk[i];
最后
return 0;