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 }
View Code

 

posted @ 2021-03-01 21:46  canwinfor  阅读(49)  评论(0)    收藏  举报