1 条题解
-
0
显然,因为操作之间可以覆盖,而尽可能大的数需要尽可能长的铺垫(对于 需要满足前面至少有 个位置),所以操作时应当是从后往前操作。
又显然,每一次操作后的 序列的每一个数都只会增加,而不会减少。
比如下面这组:
0 1 1 0 1 2 2 2 3我们先去操作最后一个三,这样后 就会变成这样
0 0 0 0 0 0 1 2 3此时我们考察倒数第二个数,可以发现不论再怎么操作,你都不能把它变成更小的数。
所以另一种无解的情况就是存在一个 ,使得存在 满足 且 。
判完无解之后,我们对于每一个 ,从后往前扫,如果扫到的 满足 ,说明这个 在我们操作 时就已经会变成相应的 了,不需要再去操作。如果大于,那么我们就把它当成一个新的起点,重新开始扫就行。
代码:
#include<bits/stdc++.h> using namespace std; int a[200005]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; if(a[i]>i-1){ cout<<-1; return 0; } } long long ans=0; for(int i=n;i>1;i--){ ans+=a[i]; int j=i-1; while(a[j]==a[i]-(i-j)){ j--; } if(a[j]<a[i]-(i-j)){ cout<<-1; return 0;; } else{ i=j+1; } } cout<<ans; return 0; }
- 1
信息
- ID
- 8665
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 2
- 上传者