总结下01分数规划:
01分数规划通常分为三类
(1)基础01分数规划
(2)最优比率生成树
(3)最优比率生成环
首先01分数规划是处理这样一类问题的,给你n个二元组,这个两个元素设为a[i] ,b[i], a[i]是得到这个物品所能得到的价值,b[i]是得到这个物品所付出的价值,让你求这样一个极值
R = sigma(a[i] * x[i]) / sigma(b[i] * x[i])求他的最大或最小,这里我们以最大为例说事。
设 F(L) = sigma(a[i] * x[i]) - L * sigma(b[i] * x[i])//注意此时的L和R的关系
化简 = sigma((a[i] - L * b[i]) * x[i])
设 d[i] = a[i] - L * b[i]
则 F(L) = sigma(d[i] * x[i])
F(L)到底到底有什么用呢?
我们假设F(L) > 0 则有 sigma(a[i] * x[i]) - L * sigma(b[i] * x[i]) > 0
转化后得到 sigma(a[i] * x[i]) / sigma(b[i] * x[i]) > L
也就是说当F(L) > 0 的时候有更大的L,也就是有更大的R,那么只要F(L) > 0我们就可以直接去找更大的L(R)直到F(L) 无限接近0为止,这里我们可以用二分去查找,理由是
F(L) = sigma(d[i] * x[i]) ,d[i] 又是随着L增加而减少的,只要能找到一种
sigma(d[i] * x[i])>=0的情况我们就可以继续往上找,说道这里直接分细化,上面说只要找到一组d[i]>=0的就可以low = mid 往上找了,这里到底有没有限制呢,当然有,限制就是上面的那三个分类,
(1)正常的情况(没有任何限制的)我们只要找到一个最大的d[i],d[i]>= 0就行了,因为是只要找到一种情况就行,我们没必要多找,但是前两天见到一个是限制必须选择n - k个的,那么就把虽有的d[i]求出来,排序,取最大的那n-k个的和,看大是否大于等于0就行了(POJ 2976)
(2)最优比率生成树,就是在我们选择的时候要找到一颗满足要求的数而已,一般都是求最小树或者最大树,然后看权值是否>=0.(POJ 2728)
(3)最优比率生成环,就是要求我们选择一个环,这个我习惯用SPFA,判断满足要求的环
(POJ 3621)
给个算法的模板吧,一共两个算法,我只写二分的那个吧。
double low = ,up = ,mid;
ans = 0;
while(up - low >= eps)
{
mid = (low + up) / 2;
if(jude(mid)) //jude()函数根据是三种中的哪个个类型而定。
ans = low = mid;
else up = mid;
}