P1570 KC 喝咖啡 - Roor - 博客园
不再赘述题目了。
这是一道典型的分数规划题目。可以参考一下 这里 的内容。这里主要讲一下笔者自己在做题时遇到的一些困惑。
为什么可以二分
我们以x[i]=1表示取第i种材料,x[i]=0表示不取。那么最后的答案会有ans=∑c[i]x[i]v[i]x[i]
我们将该式子变形一下,变成∑c[i]x[i]ans−∑v[i]x[i]=0,因此,可以设F(ans)=∑c[i]x[i]ans−∑v[i]x[i]
因为∑c[i]x[i]显然为正数,所以F(ans)单调,所以可以通过二分找零点。
为什么可以贪心
现在确定了二分的可行性,需要考虑如何二分,也即考虑check函数。
假设我们现在二分出了一个答案ansmid,我们要考虑这个答案的可行性,也即比较ansmid和∑c[i]x[i]v[i]x[i],注意到我们要求最大值,如果我们能找到一组合法的x[i]使得∑c[i]x[i]v[i]x[i]>ansmid,也即存在一种取法比当前答案更大,这代表我们答案可以更大。
但是我们发现∑c[i]x[i]v[i]x[i]>ansmid不好判断,因此将该式子变形成∑x[i](c[i]ans−v[i])<0这个式子和前面的式子是等价的,但是这个式子和零比较,更好判断。现在我们只要找到一种取法能使得变形后的式子小于零,那么就能使原式成立,也即答案可以更大。那么显然,想找是否存在一组取法让式子小于零,那就取c[i]ans−v[i]最小的就好。因此贪心也成立。