01
分数规划的思想的描述如下:令
c=(c1,c2,…,cn)
和
d=(d1,d2,…,dn)
为
n
维整数向量,那么一个
0-1
分数规划问题用公式描述如下
:FP:
最小化或者最大化
(c1x1+…cnxn)/(d1x1…dnxn)=cx/dx xi∈{0,1}。这个问题的解决已经有了成形的算法,但是网上的解释大多过难难以直接理解,大部分对于数学基础的要求是很高的。
先说说这种思想能够解决哪些问题 1:裸的01分数规划pku2976适合刚刚学习的练手以及试模板 2:01分数规划与图形的结合比如说环的判断pku3621 比如最优比例生成树pku2728 解决的思想大致一样 关键是对结论的简要证明,加深理解,然后灵活的运用。
下面谈谈解决01分数规划的方法以及结论
首先,假设要c*x/d*x最大(x,c,d均指向量),假设最优解为 val,设置这样的子问题,z(L)=c*x-d*x*L 分配x向量使 z最大,那么可以知道 如果c*x-L*x*d<0 那么无论怎么分配x向量都无法满足L值即val必然小于L 同样 我们看大于0的情况 这个时候说明可以分配x使得目标解大于L那么val必然大于L,那么很显然 L=val的时候c*x-d*x*L=0,并且z的值具有单调性下面是证明
设L1,L2,且L1>L2
z(L1) = max { c*x-L1*d*x } = c*x1-L1*d*x1(x1是使得其最大的向量)
=> z(l)是关于L的单调递减函数。
因此我们可以用二分或者迭代来解决
这里只是简单的证明并没有很严格的证明 但是对于使用来讲已经足够。
下面具体使用结论来解决上面的三道例子;
pku2976 很直接的一道题 题意就是简单01分数规划
来说说做法 由于题目已经告诉我们去掉K个x,我们要使得分数最高,设置子问题 z,根据上面的公式很容易写出程序。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
pku3621 这道题是要求一个最大(边权和/点权和)的环 同样设置子问题 边权-点权*L最大的回路,如果存在并大于0 r=mid 可以直接用spfa的判环 将权编程负值然后判断有没有负环即可
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
pku2728
最优比例生成树
说白了就是求最小的(代价权和/边权和)的生成树问题 同样设置子问题 代价权-边权*L最小 即重新构造图 然后求最小生成树 同样如果 小于0 自己推导下就会知道 r=mid 另外poj会卡stl 裸奔的prim算法能过 优先队列优化的反而超时
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
这类问题的种类很少 基本属于模板题范畴 不如动态规划这些博大精深···