CodeForces 614D 二分+贪心

原题链接:http://codeforces.com/problemset/problem/614/D

题意:有n门学科,每一门最高水平为A,一共可以提高的水平为m,计算经过提升后的最大得分,得分=(达到A分数的科目个数)*cf+(最低分数)*cm

最开始真的一脸懵逼完全不会啊
仔细想了想,可以枚举达到A的数目,把原数组从小到大排个序倒着选择成为满分的科目,然后在剩下没达到满分的科目里选择最低分。复杂度应该可以接受,我最开始想也是暴力枚举最低分判断合法好了,后来发现尼玛这不就是二分嘛

然后就愉快【呵呵】地开始码了

在check的时候真的饶了很久,最后发现其实预处理一个前缀和就很好计算了。要注意时刻维护你剩下的可以提高的分数【要保证这个值不能为负数】,至于计算的话用lower_bound找到第一个大于等于这个最小值的位置,然后就很好计算了。

多简单是吧,然后介绍我漫长【脑残】的调试过程:
1.最开始的数组要排序嘛,又要计算前缀和吗,我当时为了少打一个for循环就边读入边处理了,呵呵,错在哪多明显【于是WA在了第一个点】

2.考虑的ans的最初答案【就是不做任何改变】,但是,我没有考虑一个满分都没有的情况,最开始我想直接加到for循环里,发现不行【因为会导致j的计算少1】就只能在前面又加了一个二分最低分【于是WA在了第三个点】
然后这一天我就去睡了。= =

3.以上改完以后WA在了第五个点,好,我查。此时是晚自习。
发现第一次二分的时候求pos的时候没有考虑越界情况,于是当n=1的时候就挂了

4.接下来卡在了第19个点。我选择了找一只标程对拍。发现自己的输出答案有问题(虽然这不是我WA这个点的原因)我改写a2的地方竟然写了low。。。之后还有一个问题没找到错在哪。。
这只是一个小插曲,改了之后依旧错了,我发现我错的不是输出分数,而是输出最大得分,我的答案小了?(感谢codeforces给看数据)
漫长的查答案,不断地调整二分上下界,没用。。。
回家。
打开我的vim,打开614D的cpp,突然灵光一闪——
lower_bound()求的是大于等于的第一个数,那么我在统计小于这个数的时候是需要减1的啊啊啊啊啊啊啊啊啊啊啊啊

5.好了我A了【终于quq】

好有成就感啊,再一次见识了什么叫信息学竞赛的细节。。。。。

不过我的速度比某位dalao慢了一倍,仔细查看发现是我们二分的东西不一样,我二分的是最低分,他二分地是科目范围,从数据范围来看,前者是log(10^9),后者是log(10^5)。。。

激动到写博客留恋,虽然不是一道非常难的题。

以下AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define maxn 100010
#define ll long long
using namespace std;
typedef pair<ll,int> P;
P a[maxn];
int n,cf,cm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值