1. CF730I Olympiad in Programming and Sports
大意: $n$个人, 第$i$个人编程能力$a_i$, 运动能力$b_i$, 要选出$p$个组成编程队, $s$个组成运动队, 每个队的收益为队员能力和, 求最大收益.
费用流做法很显然, 开两个点$X,Y$表示编程和运动, 源点向每个人连边, 代价为$0$, 每个人向$X$连边, 代价为编程能力, 每个人向$Y$连边, 代价为运动能力, $X$向汇点连边容量为$p$, $Y$向汇点连边, 容量为$s$, 然后求出最大费用最大流即为答案.
考虑用堆模拟费用流. 每次增广只有四种情况.
- 添加一个未被选择的人去编程队
- 添加一个未被选择的人去运动队
- 让一个人从运动队到编程队, 再选择一个未被选择的人去运动队
- 让一个人从编程队到运动队, 再选择一个未被选择的人去编程队
前两种情况直接用堆维护最大即可. 后两种情况的话, 在每次决策时, 都把替换的收益扔进一个堆里即可.
#include
#include
#include
#include
#include
#include <set>
#include
2. NOI2019 序列
大意: 给定两个序列$a,b$, 要求每个序列选出$K$个元素, 且位置相同的元素要至少选$L$个, 求选出元素的最大和.
首先可以得到一个显然的费用流做法.
源点向$a$中每个元素连边, 代价为$a_i$, $b$中每个元素向汇点连边, 代价为$b_i$.
$a$中每个点向对应位置的$b$中的点连边.
再开两个点$X,Y$, $X$向$Y$连容量为$K-L$的边, 表示可以选出$K-L$个不一样的位置.
$a$中每个点再连向$X$, $Y$连向$b$中每个点.
最后求出源点到汇点容量为$K$的最大费用流即为答案.
考虑用堆模拟费用流, 分四种情况.
- 从$a$中选最大,$b$中也选最大 (要求X到Y仍有剩余流量)
- $a$,$b$选出位置相同
- $a$中选最大,$b$中选出之前选过的$a$对应位置
- $b$中选最大,$a$中选出之前选过的$b$对应位置
#include
#include
#include
#include
#include
#include <set>
#include
3. CF802O April Fools' Problem (hard)
大意: $n$道题, 第$i$天可以花费$a_i$准备一道题, 花费$b_i$打印一道题, 每天最多准备一道, 最多打印一道, 准备的题可以留到以后打印, 求最少花费使得准备并打印$k$道题.
这个题好有意思, 直接用堆很难模拟, 似乎可以用线段树来模拟. 一个非常好写的做法是带权二分,带权二分具体原理其实一直都没搞懂。。。
#include
#include
#include
#include
#include
#include <set>
#include
4. hdu 6698 Coins
大意: $n$组硬币, 第$i$组有一个$a_i$元的和$b_i$元的, 每组要么不选, 要么选$a_i$, 要么全选, 对于$k\le 2n$, 求出拿$k$个硬币的最大钱数.
堆模拟这四种方案即可:
- 取一个最大的$a$
- 补上一个最大的$b$
- 删掉一个$a$, 取一个最大的$a+b$
- 删掉一个$b$, 取一个最大的$a+b$
#include
#include
#include
#include
#include
#include <set>
#include