题解:P12662 [KOI 2023 Round 2] 滑冰练习
tanruiqing · · 题解
解题思路
考虑贪心。
因为对于某个点的限速
但是,这里有不合法的情况,所以我们需要修改其中的某些值来让整个序列符合要求。
考虑从前往后推。
就用样例二来解释。
4
23 7 1 5
最开始,我们会看到数字
然后,我们会看到数字
接着,我们会看到数字
后面依此类推……
这里我们可以发现,每一次更改都要从前往后检查一次序列,所以时间复杂度为
考虑从后往前推。
还是用样例二来解释。
4
23 7 1 5
最开始,我们会看到数字
然后,我们会看到数字
接着,我们会看到数字
后面依此类推……
这里我们可以发现,每一次更改都不影响前面的值,所以这里的时间复杂度为
AC 代码
AC 记录。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[500005];
int ans;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
//输入。
if(a[n]>1)a[n]=1;//如果终点前一个到达的点的速度不为1,就要将其更改为1。因为最后题目说“最后以速度 0 到达终点后结束。”,而且“每次只能从上一个经过的中间点的速度减少 1。”,所以最后一个点的限速因改为1。
for(int i=n-1;i>=1;i--){
//从后往前推。
if(a[i]>a[i+1]+1){
//如果现在这一个点的速度大于上一个点的速度+1,就无法将速度降下来,所以更改其值为a[i+1]+1。
a[i]=a[i+1]+1;
}
}
for(int i=1;i<=n;i++){
ans+=a[i];
}
//最后累加答案。
cout<<ans;//输出。
return 0;
}