C. Pekora and Trampoline ###K //K
题目链接:https://codeforc.es/contest/1491/problem/C
题意:给定数组s[i] 要求把所有的s[i]减为1 规则是 从i开始 每次可以跳到i+s[i] 跳到的地方数字减1
最低减到1 每次跳出n才算结束,问最少跳多少次可以满足题意
思路:考虑贪心,在前面的肯定要往后跳,因为没有人可以使得他减少, 用vis[i] 代表i被跳到的次数
每次当s[i] 不是1的时候 那么 [i+2,min(n,i+s[i])) 这些都被跳到一次, 标记vis[j]++
当vis[i]>=s[i] 的时候说明 i+1也被跳到了, 然后每次的贡献就是max(0,s[i]-1-vis[i]) 累加即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=5e3+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define pi pair<int,int> 7 #define fi first 8 #define sc second 9 #define pb push_back 10 ll vis[maxn]; 11 ll s[maxn]; 12 13 14 15 int main() 16 { 17 ios::sync_with_stdio(0); 18 cin.tie(0); 19 int t; 20 cin>>t; 21 while(t--) 22 { 23 int n; 24 cin>>n; 25 for(int i=1;i<=n;i++) vis[i]=0; 26 for(int i=1;i<=n;i++) cin>>s[i]; 27 ll ans=0; 28 for(int i=1;i<=n;i++) 29 { 30 if(s[i]>=2) 31 { 32 for(int j=i+2;j<=min(n,(int)s[i]+i);j++) 33 vis[j]++; 34 } 35 ll tt=vis[i]-(s[i]-1); 36 if(tt>0) vis[i+1]+=tt; 37 tt=s[i]-1-vis[i]; 38 if(tt>0) ans+=tt; 39 } 40 cout<<ans<<'\n'; 41 } 42 43 44 45 46 47 }

浙公网安备 33010602011771号