题意
现在有三种物品,给出的格式为(t[i],x[i])如下:
- 拉环罐头,被标记为t[i]=0,得到即食,可以得到x[i]的开心值。
- 普通罐头,被标记为t[i]=1,需要用开罐器打开,食用后可以得到x[i]的开心值。
- 开罐器,被标记为t[i]=2,使用后可以打开x[i]个普通罐头。
现在有N个这样的物品,你可以选择其中的M个,求你可以获得的最大开心值。
思路
首先我们可以很轻松的想到暴力的方法,即循环枚举选择的拉环罐头的个数和普通罐头的个数,然后求解,这样显然会超时。我们现在采取贪心的思路:当我们确定拉环罐头的个数i后,那么剩下的much-i个物品,我们肯定是喜欢其中普通罐头的个数是越多越好的,毕竟在拉环罐头的个数确定之后,唯一获得开心值的途径就是普通罐头,但是普通罐头需要开罐器打开,那么两者间就形成了一个相互制约的关系:普通罐头越多,开罐器越少,不能全部开完;普通罐头越少,开罐器越多,可以全部开完。这样大致形成了一个单调关系,那么这个时候我们可以采取二分答案:在much-i里二分出普通罐头的选取数量x,在保证能全部打开的情况下的最大普通罐头数量。那么这个时候check函数就很好些了,我们同时维护三个前缀和,当普通罐头的数量x确定后,我们就得到了开罐器的数量,即much-i-x,我们再查看开罐器前缀和的数量前缀和是否大于等于x即可。
代码
https://atcoder.jp/contests/abc312/submissions/54068470