浅谈01分数规划

  • 对于形如求使得 ∑ a i ∑ b i \frac {\sum a_i}{\sum b_i} biai 最值的问题 , 称为 01 01 01 分数规划 (选择一些 a a a b b b 使得其某两属性之和的商取到最值)

  • 此题一般解法为二分答案求出最大最小值

  • 假如我们要求最大的 ∑ a i ∑ b i \frac{\sum a_i}{ \sum b_i} biai

    a n s = ∑ a i ∑ b i ans=\frac{\sum a_i}{ \sum b_i} ans=biai 也就是 ∑ ( a i − a n s ∗ b i ) = 0 \sum (a_i-ans*b_i)=0 (aiansbi)=0

    当前二分的答案为 m i d mid mid

    如果 ∑ ( a i − m i d ∗ b i ) ≥ 0 \sum (a_i-mid*b_i)\ge 0 (aimidbi)0 , 那么 m i d ≤ a n s = ∑ a i ∑ b i mid\le ans=\frac{\sum a_i}{ \sum b_i} midans=biai , 说明 m i d mid mid 可行 , 放大范围


  • 例题1

    题意:每个物体 i i i 有两个属性 a i , b i a_i,b_i ai,bi , 选 n − k n-k nk 个 , 求最大的 ∑ a i ∑ b i \frac{\sum a_i}{ \sum b_i} biai

    ( a i − m i d ∗ b i ) (a_i- mid*b_i) (aimidbi) 变成这些物体的新属性 c i c_i ci , 而问题没有其他限制 , 直接选 c c c 最大的 n − k n-k nk 个 , 然后根据上文所述进行二分

    代码


  • 例题2

    题意:每个点有两个属性 a i , b i a_i,b_i ai,bi , 在树上选 n − m n-m nm 个点 , 要求他们之间联通 , 求最大的 ∑ a i ∑ b i \frac{\sum a_i}{ \sum b_i} biai

    ( a i − m i d ∗ b i ) (a_i- mid*b_i) (aimidbi) 变成这些物体的新属性 c i c_i ci, 问题就变为了在树上选一些点且要求联通, 使得其 c c c 之和大于等于 0 0 0 , 那么满足最大的 ∑ c \sum c c 大于等于 0 0 0 即可

    代码


  • 例题3

    题意 :每头牛有两个属性 t i , w i t_i,w_i ti,wi , 选任意头 , 要求 ∑ w i ≥ W \sum w_i\ge W wiW , 求最大 ∑ t i ∑ w i \frac{\sum t_i}{\sum w_i} witi

    ∑ ( t i − m i d ∗ w i ) ≥ 0 \sum(t_i-mid* w_i)\ge 0 (timidwi)0 a n s ≥ m i d ans\ge mid ansmid

    ( t i − m i d ∗ w i ) (t_i-mid* w_i) (timidwi) 作为新属性 x i x_i xi , 要求 ∑ w i ≥ W \sum w_i\ge W wiW , 若此时最大的 ∑ x i ≥ 0 \sum x_i\ge 0 xi0 则放大

    至于如何求最大的 ∑ x i \sum x_i xi 并满足 ∑ w i ≥ W \sum w_i\ge W wiW , 其实就是一个背包问题

    代码


  • 例题4

    题意 : n n n 个点 , 有 m m m 条单向边 , 每条边有两个属性 c , w c,w c,w , 要求选择的边构成一棵树 , 求最大的 f − ∑ c i ∑ t i \frac{f-\sum c_i}{\sum t_i} tifci ( f f f 给定)

    a n s = f − ∑ c i ∑ t i ans= \frac{f-\sum c_i}{\sum t_i} ans=tifci

    ∑ ( m i d ∗ t i + c i ) ≤ f \sum(mid*t_i+c_i)\le f (midti+ci)f , 那么 m i d ≤ a n s mid\le ans midans 放大 m i d mid mid

    ( m i d ∗ t i + c i ) (mid*t_i+c_i) (midti+ci) 变成一条道路的新属性 x i x_i xi , 而问题要求联通 , 实则是最小生成树问题.

    代码


  • 例题5

    题意:给定一张带权有向图 , 边的权值为 w w w , 选若干条边构成环 , 求最小的 ∑ w i 边 的 个 数 \large\frac{\sum w_i}{边的个数} wi

    a n s = ∑ w i ∑ c n t i ans=\large\frac{\sum w_i}{\sum cnt_i} ans=cntiwi ( c n t i = 1 ) (cnt_i=1) (cnti=1)

    ∑ ( w i − m i d ) < 0 \sum(w_i-mid)<0 (wimid)<0 说明 m i d > a n s mid>ans mid>ans , 则继续缩小范围

    ( w i − m i d ) (w_i-mid) (wimid) 变成一条边的新边权 , 问题即变为判断负环 , 考虑使用 S P F A SPFA SPFA

    代码


例题6
题解

你可能感兴趣的:(学习笔记,算法,c++)