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\)。