CodeForces #664D - Boboniu Chats with Du

传送门

题意

n个数,对于每个数ai,如果ai>m,则接下来d个数无法计算,否则计算进总值,求可得的最大总值。

思路

因为n,d小于1e5,可以考虑暴力枚举,这道题比较巧妙的是他枚举的是ai>m的次数,并从大到小枚举,而用前缀和每次计算都是o(1)的效率,暴力枚举取x个大于m的,那么会消耗(x−1)(d+1)+1天,剩余的天数如果能取<m的,全部取<m的肯定是最优的

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define maxn 100005
#define mod 998244353
ll a[maxn],b[maxn];

bool cmp(ll x,ll y){
    return x>y;
}

int main(){
    ll i, n, j, k, t, m,d;
    scanf("%lld%lld%lld",&n,&d,&m);
    ll cura=0,curb=0;
    for(i=1;i<=n;i++){
        scanf("%lld",&k);
        if(k>m)
            a[++cura]=k;
        else b[++curb]=k;
    }
    sort(a+1,a+1+cura,cmp);
    for(i=2;i<=cura;i++) a[i]+=a[i-1];
    sort(b+1,b+1+curb,cmp);
    for(i=2;i<=n;i++) b[i]+=b[i-1];
    ll ans=b[n];
    for(i=1;i<=cura;i++){
        j=(i-1)*(d+1)+1;
        if(j>n) break;
        ans=max(ans,a[i]+b[n-j]);
    }
    printf("%lld\n",ans);
}