Codeforces 1203F2 Complete the Projects (hard version) 贪心

传送门

思路:

首先b>=0的项目不难处理,根据a值从小到大排序,能完成则r+=b[i]即可.关键是在于处理b<0的项目.

对于b<0的项目采用贪心策略:

先根据a值从大到小排序,每遍历到一个,就看它是否可以完成,如果可以,r+=b[i]并且标记i为完成状态. 如果不可以,看它是否可以替换之前已经完成的项目.假设j是某个之前已经完成的项目,i为当前不可完成项目,替换的条件为r-b[j]>=a[i]&&r-b[j]+b[i]>=0&&b[j]<=b[i],那么对于多个可以替换的项目,应该选哪个进行替换? 肯定是选替换后可以使r的值最大的那个,设i要替换j.替换完之后, 有一些不可完成的项目又变得可以完成了(最多只会有一个这样的项目,请仔细考虑,因为之前不可以完成的项目,肯定是因为它的b值太小了,它替换掉任意一个已经完成的项目都会使得r减小.而且这个项目必须要放在i的下一个去完成,如果放在i的前面,会导致未解决i之前的r值变得更小,就更无法解决i了,还有可能会影响i之前那些已经完成的任务.例如,j已经完成,i不能完成,现在i要替换j,有一个k是未完成的状态,我们现在想完成这个k必须将k放在i之后完成,如果k放在i之前完成,必定导致i不可能完成,因为k之所以是未完成状态,是因为k比j的b要小,所以如果不去完成j,而是先完成k,再去完成i,势必导致i不可以完成),所以再遍历i-1到1,找出之前没被完成但现在可以完成了并且使得剩余的r最大的那个项目,设置为完成状态.

 

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cst
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值