1 条题解
-
0
题意简化
个时刻,每个时刻选择睡觉(S)或吃东西(E):
- 睡觉:获得愉悦值
- 吃东西:获得愉悦值
约束:每个长度为 的连续区间 中:
- 至少有 个时刻睡觉
- 至少有 个时刻吃东西
求最大总愉悦值,并输出方案。
核心思想:网络流建模
1. 转化为流量平衡问题
设 表示时刻 吃东西, 表示睡觉。
约束条件:对每个区间 :
- 睡觉数 ⇒ 吃东西数
- 吃东西数 ⇒ 睡觉数
即:
2. 差分约束转网络流
设前缀和 ,则区间和约束变为:
即:
同时有 (每个时刻最多一个选择)。
3. 最小费用最大流建模
代码中的网络流模型:
- 源点 ,汇点
- 节点 表示前缀和
边的含义:
E(0, 1, k-ms, 0): 到 的流量限制E(i, i+1, k-me-ms, 0): 且 的约束E(max(1,i-k+1), i+1, 1, e[i]-s[i]):选择时刻 吃东西的决策边- 流量1表示选择
- 费用 (选择吃东西比睡觉多获得的愉悦值)
4. 费用流的直观解释
初始假设所有时刻都睡觉,总愉悦值为 。
考虑将某些时刻改为吃东西:
- 获得额外愉悦值
- 但需满足区间约束
网络流找到一组改变,使得额外愉悦值最大且满足约束。
算法步骤
-
建图:
- 建立 个节点
- 添加区间约束边
- 添加决策边:每个时刻对应一条边,流量1,费用
-
跑最小费用最大流:
- 使用带势能的Dijkstra优化
- 初始用SPFA计算势能
-
计算答案:
- 基础值:
- 加上最大费用流的值
-
输出方案:
- 检查每条决策边:如果流量为0(边被使用),表示选择了吃东西(E)
- 否则选择睡觉(S)
关键点
1. 区间约束的建模技巧
将区间和约束转化为前缀和差分约束,再转化为网络流中的容量限制。
2. 决策边的巧妙设计
- 每个时刻对应一条从 到 的边
- 流量1表示选择
- 费用为收益差
3. 网络流规模
- 节点数:
- 边数:
- 使用带势能的Dijkstra,复杂度 ,可过
代码特点
- 网络流模板:封装了最小费用最大流
- 势能优化:先用SPFA计算初始势能,再用Dijkstra
- 方案输出:通过检查边的剩余流量判断选择
- 边编号记录:
id[i]记录每个时刻对应的决策边
样例解释
输入:
5 4 2 2 4 8 6 2 2 (s_i) 4 6 9 6 0 (e_i)约束:每个长度为4的区间要有至少2个S和2个E。
输出:
SSEES- 时刻1:S,得4
- 时刻2:S,得8
- 时刻3:E,得9
- 时刻4:E,得6
- 时刻5:S,得2 总和:4+8+9+6+2 = 29
网络流找到最优方案:将时刻3和4改为吃东西。
- 1
信息
- ID
- 6013
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者