感受
怎
么
这
么
傻
逼
的
题
目
,
我
现
场
A
不
了
呢
?
看
来
还
有
不
少
提
升
的
空
间
怎么这么傻逼的题目,我现场A不了呢?看来还有不少提升的空间
怎么这么傻逼的题目,我现场A不了呢?看来还有不少提升的空间
题意
简
单
来
说
,
给
你
n
天
,
每
一
天
都
有
一
个
f
u
n
值
,
如
果
该
值
大
于
m
,
则
选
择
该
天
,
然
后
后
d
天
不
能
选
择
。
否
则
,
不
影
响
,
问
最
优
情
况
下
可
以
获
得
的
最
大
f
u
n
之
和
简单来说,给你n天,每一天都有一个fun值,如果该值大于m,\\则选择该天,然后后d天不能选择。否则,不影响,问最优情况下\\可以获得的最大fun之和
简单来说,给你n天,每一天都有一个fun值,如果该值大于m,则选择该天,然后后d天不能选择。否则,不影响,问最优情况下可以获得的最大fun之和
思路
贪
心
想
,
然
后
会
发
现
一
个
很
牛
逼
的
性
质
。
现
场
打
的
时
候
就
像
个
智
障
,
不
知
道
使
用
,
硬
生
生
在
哪
里
贪
心
写
。
贪心想,然后会发现一个很牛逼的性质。现场打的时候就像个智障\\,不知道使用,硬生生在哪里贪心写。
贪心想,然后会发现一个很牛逼的性质。现场打的时候就像个智障,不知道使用,硬生生在哪里贪心写。
转
入
正
题
:
转入正题:
转入正题:
我
们
考
虑
一
个
最
简
单
的
贪
心
,
那
就
是
a
i
<
=
m
(
集
合
S
)
的
能
选
就
选
,
对
于
>
m
(
集
合
T
)
的
则
需
要
另
外
考
虑
。
我们考虑一个最简单的贪心,\\那就是a_i<=m(集合S)的能选就选,\\对于>m(集合T)的则需要另外考虑。
我们考虑一个最简单的贪心,那就是ai<=m(集合S)的能选就选,对于>m(集合T)的则需要另外考虑。
怎
么
考
虑
呢
?
很
贪
心
地
想
,
就
是
利
用
S
中
的
较
小
元
素
进
行
换
,
有
没
有
发
现
一
个
性
质
:
S
(
元
素
升
序
)
,
T
(
元
素
升
序
)
,
最
优
答
案
一
定
是
选
择
S
的
某
一
个
后
缀
,
然
后
再
贪
心
选
择
T
的
某
个
后
缀
。
怎么考虑呢?很贪心地想,就是利用S中的较小元素进行\\换,有没有发现一个性质:\\S(元素升序),T(元素升序),最优答案一定是选择S的\\某一个后缀,然后再贪心选择T的某个后缀。
怎么考虑呢?很贪心地想,就是利用S中的较小元素进行换,有没有发现一个性质:S(元素升序),T(元素升序),最优答案一定是选择S的某一个后缀,然后再贪心选择T的某个后缀。
这
样
,
这
个
问
题
不
就
S
o
−
E
a
s
y
了
吗
?
枚
举
S
的
后
缀
(
可
以
为
空
)
,
然
后
贪
心
选
择
T
的
后
缀
,
怎
么
选
呢
?
举
个
栗
子
,
如
果
我
们
选
择
S
的
后
缀
长
度
为
i
,
那
么
也
就
是
说
∣
S
∣
−
i
个
天
数
会
被
剩
余
,
那
问
题
就
转
化
为
∣
S
∣
−
i
+
∣
T
∣
中
,
尽
可
能
在
T
中
选
最
大
后
缀
这样,这个问题不就So-Easy了吗?\\枚举S的后缀(可以为空),然后贪心选择T的后缀,怎么选呢?\\举个栗子,如果我们选择S的后缀长度为i,那么也就是说|S|-i个天数会被剩余,那问题就转化为|S|-i+|T|中,尽可能\\在T中选最大后缀
这样,这个问题不就So−Easy了吗?枚举S的后缀(可以为空),然后贪心选择T的后缀,怎么选呢?举个栗子,如果我们选择S的后缀长度为i,那么也就是说∣S∣−i个天数会被剩余,那问题就转化为∣S∣−i+∣T∣中,尽可能在T中选最大后缀
详 情 可 以 参 考 代 码 , 很 简 单 的 , 一 下 就 看 懂 了 ! 详情可以参考代码,很简单的,一下就看懂了! 详情可以参考代码,很简单的,一下就看懂了!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
ll sum[maxn], a[maxn];
int n, d, pos; ll m;
ll solve(int res){
res = res + n - pos;
int cnt = res / (d + 1); if(res % (d + 1)) cnt++;
cnt = min(cnt, n - pos);
int l, r; r = n; l = n - cnt + 1;
return sum[r] - sum[l - 1];
}
void print(){
puts("*********************");
for(int i = 1; i <= pos; i++){
printf("%lld ", a[i]);
}
putchar('\n');
for(int i = pos + 1; i <= n; i++){
printf("%lld ", a[i]);
}
putchar('\n');
puts("*********************");
}
int main(){
scanf("%d%d%lld", &n, &d, &m);
for(int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
}
sort(a + 1, a + n + 1); pos = upper_bound(a + 1, a + n + 1, m) - a; pos--;
for(int i = 1; i <= n; i++){
sum[i] = sum[i - 1] + a[i];
}
ll ans = 0, tmp;
for(int i = 1; i <= pos + 1; i++){
tmp = sum[pos] - sum[i - 1];
tmp += solve(i - 1);
ans = max(ans, tmp);
}
printf("%lld\n", ans);
return 0;
}