|
|
|
@ -226,28 +226,51 @@ signed main() {
|
|
|
|
|
|
|
|
|
|
**思路**
|
|
|
|
|
|
|
|
|
|
这是一道难度入门的良心题~
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
题意很明了,可以传送一次,求$1$到$n$耗费的最少时间
|
|
|
|
|
上图是一个$n = 6$的样例。从城市$1$到城市$6$,需要$3+2+4+5+4=18$天。
|
|
|
|
|
|
|
|
|
|
很明显,可以贪心,最长的$k$段选择传送,其余步行
|
|
|
|
|
假如传送器的半径为$2$。可以逐个枚举。
|
|
|
|
|
|
|
|
|
|
求两地之间用时使用前缀和,$s[i]$表示$a_1$到$a_i$之和
|
|
|
|
|
- 如果在城市$1$使用传送器,则一下子可到达城市$3$,然后城市$3$到城市$6$,需要$13$天。这种情况下从城市$1$到城市$6$,需要$13$天。
|
|
|
|
|
|
|
|
|
|
那么使用传送器可以节省时间可表示为$s[k+i]-s[i]$ (有效区间$[i+1,i+k]$)
|
|
|
|
|
- 如果在城市$2$使用传送器,则从城市$1$先用$3$天的时间到达城市$2$,再用传送器到达城市$4$,从城市$4$到城市$6$需要$9$天。这种情况下从城市$1$到城市$6$,共需要$3 + 9 = 12$天。
|
|
|
|
|
|
|
|
|
|
扫一遍找到节省时间最大值,答案即是$1$到$n$之间步行用时减去传送节省时间
|
|
|
|
|
然而稍不注意就只有$92$分,似乎坑到了一部分人(比如本蒟蒻)
|
|
|
|
|
- 如果在城市$3$使用传送器,则从城市$1$到城市$3$需要$5$天,从城市$3$使用传送器一下子到达城市$5$,从城市$5$到城市$6$需要$4$天。这种情况下从城市$1$到城市$6$,共需要$5+4=9$天。
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
- 如果在城市$4$使用传送器,则从城市$1$到城市$4$需要$9$天,从城市$4$使用传送器一下子到达城市$6$。这种情况下从城市$1$到城市$6$,共需要$9$天。
|
|
|
|
|
|
|
|
|
|
原因很简单,$s[k+i]-s[i]$中的$i$要从$0$开始循环而不是从$1$开始
|
|
|
|
|
显而易见,若$k=1$,那么$s[1+1]-s[1]$表示的是$2 , 3$两地之间用时
|
|
|
|
|
所以如果从$1$开始循环就会漏掉从$1$地到$1+k$地之间的用时
|
|
|
|
|
从$0$开始循环就可以$AC$了!
|
|
|
|
|
- 如果在城市$5$使用传送器,则从城市$1$到城市$5$需要$14$天,从城市$5$使用传送器一下子到达城市$6$。这种情况下从城市$1$到城市$6$,共需要$14$天。
|
|
|
|
|
|
|
|
|
|
所以在城市$3$或城市$4$使用传送器,可以使得总共花费的时间最少。
|
|
|
|
|
|
|
|
|
|
**$Code$**
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
#define int long long
|
|
|
|
|
#define endl "\n"
|
|
|
|
|
const int N = 1000010;
|
|
|
|
|
int n, k;
|
|
|
|
|
int a[N], s[N];
|
|
|
|
|
int ans = LONG_LONG_MAX; // 预求最小先设最大
|
|
|
|
|
|
|
|
|
|
signed main() {
|
|
|
|
|
cin >> n >> k;
|
|
|
|
|
for (int i = 2; i <= n; i++) { // i代表第i个城市
|
|
|
|
|
cin >> a[i]; // a[i]代表第i-1个城市到第i个城市需要的时间
|
|
|
|
|
s[i] = s[i - 1] + a[i]; // 利用前缀存储从第1个城市到第i+1个城市的累积时间
|
|
|
|
|
}
|
|
|
|
|
// 感悟:代码越多,可读性越强
|
|
|
|
|
for (int i = 1; i <= n; i++) { // 遍历每个城市
|
|
|
|
|
int far = i + k; // 传送到最远的点
|
|
|
|
|
if (far >= n) far = n; // 最远不能超过n点
|
|
|
|
|
int time = s[i] + s[n] - s[far]; // s[n]-s[far]= 剩余道路需要走的时间,s[i]:前面道路需要走的时间
|
|
|
|
|
ans = min(ans, time); // 取最小值
|
|
|
|
|
}
|
|
|
|
|
cout << ans << endl; // 输出
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### [$P1719$ 最大加权矩阵](https://www.luogu.com.cn/problem/P3406)
|
|
|
|
|
|
|
|
|
|