C. Racing (thinking + greedy)

Although it is a sign-in, the question is pretty good.

Idea: First of all, you can see that it has nothing to do with the order, so sort.

The sequence after sorting is as follows:

  Original score a1 a2 a3 a4 a5 a6 a7

  Increase score: 7 6 5 4 3 2 1

If you want to maximize a1, let a1+7. At the same time, since the sequence is a single increase, greedy makes the increase score decrease. If at this time there is a total score greater than him, then he will never be a championship.

What about a4? We are also greedy to let a4+7, and pay attention to adding 7. At this time, the number in front of a4 should be smaller than a4, and the added score should be smaller than a4, so naturally we don’t need to consider it. To make the number behind a4 as small as possible, then in the same way, let the one with more bonus points be placed before a4, and the latter with less bonus points, which is decreasing.

How to quickly determine whether the new value formed by adding a fixed value to the following sequence is greater than the current value + n.

Can st/line segment tree. But yesterday’s experience shows that: just take the maximum value of the suffix .

   

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=3e5+1000;
typedef long long LL;
LL a[maxn],b[maxn];
LL sum[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  sum[n+1]=0;
  for(LL i=1;i<=n;i++){
    cin>>a[i];
  }
  sort(a+1,a+1+n);
  for(LL i=1;i<=n;i++){
    b[i]=n-i+1;
  }
  for(LL i=n;i>=1;i--){
    sum[i]=max(sum[i+1],b[i]+a[i]);
  }
  LL ans=1;
  for(LL i=1;i<=n-1;i++){
    if(a[i]+n>=sum[i+1]){
        ans++;
    }
  }
  cout<<ans<<endl;
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/112981822