codeforces D. Boboniu Chats with Du

codeforces D. Boboniu Chats with Du_第1张图片

题目

题意:

给你一个 a a a序列,对于每一个 a i a_i ai,如果此时的 a i > m a_i>m ai>m,那么接下去的 d d d a i a_i ai将无效,在可以将 a a a序列重新排列的情况下,有效的 a i a_i ai的总和最大是多少。

思路:

我们先将 a i ≤ m a_i\leq m aim的数量得出来,记作 k k k,那么我们假设选择的 a i > m a_i>m ai>m的个数为 x x x ( x ≤ n − k ) (x \leq n-k) (xnk),那么最大有效的就是 ( n − 1 ) / ( d + 1 ) + 1 (n-1)/(d+1)+1 (n1)/(d+1)+1,此时就是 a n > m a_n>m an>m,然后我们就是不断枚举 x ( x ≤ n − k , x ≤ ( n − 1 ) / ( d + 1 ) + 1 ) x(x\leq n-k ,x\leq(n-1)/(d+1)+1) x(xnk,x(n1)/(d+1)+1),然后对于每一个 x x x,计算出最后的答案并且取最大。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
template <class T>
inline void read(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return ;
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1:1;
    ret = (c == '-') ? 0:(c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return ;
}
inline void outi(int x) {if (x > 9) outi(x / 10);putchar(x % 10 + '0');}
inline void outl(ll x) {if (x > 9) outl(x / 10);putchar(x % 10 + '0');}
const int maxn = 1e5 + 10;
ll a[maxn], cnt[maxn];
int main() {
    int n, d, m; read(n), read(d), read(m);
    for (int i = 1; i <= n; i++) read(a[i]);
    sort(a + 1, a + n + 1);
    int k = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i] <= m) k++;
        cnt[i] = cnt[i - 1] + a[i];
    }
    ll ans = cnt[k];
    for (int i = n, j = 1; i >= 1 && j < n - k + 1; i -= d + 1, j++) {
        ans = max(ans, cnt[k] - cnt[max(0, k - i + 1)] + cnt[n] - cnt[n - j]);
    }
    printf("%lld", ans);
    return 0;
}

你可能感兴趣的:(codeforces)