【总结】01分数规划

01分数规划指的是这么一类问题:
有两个长度为\(n\)的数列\(a\)\(b\),要求使下式值最大

\[\frac{\sum_{i=1}^na_i\times c_i}{\sum_{i=1}^nb_i\times c_i} \]

其中\(c_i=0\)\(1\)
就是对于每组\(a,b\)由你决定选与不选,使得选出的所有\(a\)的和和\(b\)的和的商最大。

解决这类问题,通常采用二分答案的方法。
假设最大值为\(ans\),则一定有:

\[\frac{sum_a}{sum_b}<=ans \]

其中\(sum_a\)\(sum_b\)分别是任何一种选取情况下\(a\)的总和和\(b\)的总和。
移项得:

\[sum_a<=ans\times sum_b \]

再移:

\[sum_a-ans\times sum_b<=0 \]

展开得:

\[\sum_{i=1}^na_i\times c_i-ans\times \sum_{i=1}^nb_i\times c_i<=0 \]

合并得:

\[\sum_{i=1}^n(a_i-ans\times b_i)\times c_i<=0 \]

如果无论如何这个式子都成立,说明当前的\(ans>=\)最优解。
于是二分\(ans\),看最大的\(a_i-b_i\times ans\)是否小于等于\(0\)就行了。
如果不大于\(0\),则说明当前的\(ans\)大于等于真正的\(ans\),如果大于\(0\),则说明当前\(ans\)小于真正\(ans\)

当然不会有裸题,如果加一个限制条件“至少选\(k\)个”,我们就是不是看最大的了,而是要对前\(k\)大求和,看是否小于等于\(0\)

当然求最大的\(\sum a[i]-b[i]\times ans\)的方法也可能没这么简单,比如《新生舞会》那题就要用费用流去求最大的\(\sum a[i]-b[i]\times ans\)\(check\)

posted @ 2019-02-02 19:42  Qihoo360  阅读(156)  评论(0编辑  收藏  举报
You're powerful!