分数规划小结

Preface

其实分数规划就是化下式子,然后套个二分就没了... 所以分数规划的问题的核心并不在分数规划的部分

Description

给你(n)个元素,每一个元素都有两个权值(a_i, b_i),你需要选择若干个元素,最大/小化(frac{sum a_i}{sum b_i})

Process

我们可以先二分一个答案每次只需要判断和不合法即可,假设答案为(ans),并且需要最大化分数

[frac{sum a_i}{sum b_i} geq ans \ sum a_i - ans cdot sum b_i geq 0 \ sum(a_i - ans cdot b_i) geq 0 ]

这样我们就只需要令一件物品的权值(w_i = a_i - ans cdot b_i),然后判断是否能选出一些物品使得(sum w_i geq 0)即可

2分钟讲完分数规划

Problem

[POJ2976] Dropping tests

给你(n)个物品,每一个物品都有两个权值(a_i, b_i),你需要选出(k)个物品,最大化

[100 cdot frac{sum_{i = 1}^{n} a_i}{sum_{i = 1}^{n} b_i} ]

答案四舍五入至整数

(n leq 1000, 0 leq k < n)

Solution

这就是一道板子题,直接照着前面的方法做

<p>每次对$w_i$排一遍序,然后取最大的$k$个加起来看是不是大于等于$0$就可以了</p>

[Luogu4322] 最佳团体

给你一棵树(点编号(0)(n)),每一个节点都有两个属性(p_i, s_i)

你需要在树上选择(k + 1)个节点,并且选择一个节点的前提选择它的父亲节点(根结点除外),并且最大化(frac{sum p_i}{sum s_i})

(k leq n leq 2500)

Solution

就直接套一个分数规划,然后再做一遍树形依赖背包就可以了

<p>考虑到可能会有$10^{-10}\%$的人像我一样,可能会不知道树形依赖背包,所以我还是讲一下</p>

<p>我们可以把这棵树转换为$dfn$序,然后就可以在dfn序上$dp$了,设$sz[x]$为以$x$为根的子树的大小</p>

<p>有转移方程
$$
	dp[i][j] = max(dp[i + 1][j - 1], dp[i + sz[i]][j])
$$
最后答案就是$dp[0][k + 1]$</p>

<p><a href = "https://paste.ubuntu.com/p/Mct5ztjHN5/">Code</a></p>

[Luogu3199] [HNOI2009]最小圈

给你一个(n)个点(m)条边的带权有向图,你需要找到这个图中最小权值的环

定义一个环的权值为这个环上所有边边权的平均值

Solution

对于这种题目,我们可以对其建模,然后转换为分数规划问题

<p>我们可以令每一条边有两个边权$a_i, b_i$,其中$a_i$等于边权,$b_i$等于$1$</p>

<p>然后就直接套分数规划,然后判断有没有负环就可以了</p>

[POJ2728] Desert King

一个国家有(n)座城市,每一个城市都有一个坐标(x_i, y_i)和一个海拔(h_i)

你需要在城市之间修建恰好(n - 1)条道路,使得所有的城市之间都可以互相到达

一条道路的长度为两个端点的欧几里得距离,花费为端点的海拔差

现在你需要修建这些道路,并且要最小化总花费与总长度的比值,输出这个比值

(n leq 1000)

Solution

首先看到比值,就直接转化为分数规划问题

<p>不难发现,如果直接每次用$kruskal$跑最小生成树显然是会T的,因为可能是完全图</p>

<p>所以我们可以写一个$n^2$的prim来跑 (这东西虽然平时用的不多,但搞稠密图还是有一点用的)</p>

<p><del>另外,本题莫名卡精度</del></p>

<p><a href = "https://paste.ubuntu.com/p/cXTZPzckm4/">Code</a></p>

[Luogu2868] [USA07DEC]观光奶牛

给你一个有向图,每一个点有一个权值(f_i),每一条边有一个权值(w_i)

你需要选择一个点,然后以这个点为起点,遍历若干个节点(至少两个)然后回到原点。这时你的快乐值为(frac{sum f_i}{sum w_i})(多次经过一个点只算一次(f_i)(w_i)可以多次计算)

请问最大的快乐值为多少

Solution

我们先套一个分数规划之后,把一条边的权值看成$b_i$,它所指向的点看成$a_i$,不难发现就是要求一个负环

<p>但是多次经过一个点只会计算一次的限制有怎么处理呢?</p>

<p>我们可以发现如果一个复杂环为负数,那么构成这个复杂环的简单环中至少有一个为负数,所以找到哪个负环都是等价的</p>
原文地址:https://www.cnblogs.com/xunzhen/p/10414817.html