分数规划小结

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>
posted @ 2019-02-21 19:32  xunzhen  阅读(516)  评论(1编辑  收藏  举报