给你一个 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 ai≤m的数量得出来,记作 k k k,那么我们假设选择的 a i > m a_i>m ai>m的个数为 x x x个 ( x ≤ n − k ) (x \leq n-k) (x≤n−k),那么最大有效的就是 ( n − 1 ) / ( d + 1 ) + 1 (n-1)/(d+1)+1 (n−1)/(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(x≤n−k,x≤(n−1)/(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;
}