Solution -「NEERC 2016」Delight for a Cat 的一个尝试
\(\mathscr{Description}\)
Link.
给定 \(n,k,m_s,m_e\) 和两个长为 \(n\) 的序列 \(\{s\},\{e\}\), 选择一个 \(S\subseteq[1,n]\cap\mathbb N\), 满足 \(\forall l\in[1,n-k+1],~\sum_{i=l}^{l+k-1}[i\in S]\in[m_s,k-m_e]\), 并最大化 \(\sum_{i=1}^n([i\in S]s_i+[i\notin S]e_i)\).
\(n\le10^3\).
\(\mathscr{Solution}\)
这里一个机械化方法的尝试, 没写代码是因为不可告人的原因. (
我们想求
\max & \displaystyle \sum_{i=1}^ne_i+\sum_{i=1}^n(s_i-e_i)(x_i-x_{i-1})\\
\text{s.t.} & x_0=0\\
& x_i\ge x_{i-1} & (\forall i>0)\\
& x_{i-1}-x_{i}\ge-1 & (\forall i>0) \\
& x_i-x_{i-k}\ge m_s & (\forall i\ge k)\\
& x_{i-k}-x_i\ge m_e-k & (\forall i\ge k)
\end{array}\tag1
\]
先忽略 \(x_0=0\) 这个约束. 从现在起, 我们停止思考, 直接去套这个 trick. 通过足够大的代价 \(I\) 间接限定 \(\ge\):
(1)\Leftrightarrow \max\quad & \sum_{i=1}^n e_i+\sum_{i=1}^n(s_i-s_{i+1}-e_i+e_{i+1})x_i\\
&-\sum_{i=1}^n\max\{x_{i-1}-x_i,0\}I\\
&-\sum_{i=1}^n\max\{x_i-x_{i-1}-1,0\}I\\
&-\sum_{i=k}^n\max\{m_s+x_{i-k}-x_i,0\}I\\
&-\sum_{i=k}^n\max\{m_e-k+x_i-x_{i-k},0\}I.
\end{aligned}
\]
注意到这个形式满足模型
\]
因此可以直接翻译为费用流建图. 先取个负把 \(\max\) 变成 \(\min\), 令 \(b_i=s_{i+1}-s_i+e_i-e_{i+1}\), 流网络 \(G=(V,E)\) 建图如下:
V &= \{S,T\}\cup\{1,2,\dots,n\},\\
E &= \{\lang S,i,b_i,0\rang\mid b_i>0\} \cup \{\lang u,T,-b_i,0\rang\mid b_i<0\}\\
&\cup \{\lang i,i-1,I,0\rang\}\cup\{\lang i-1,i,I,1\rang\}\\
&\cup \{\lang i,i-k,I,-m_s\rang\}\cup\{\lang i-k,i,I,k-m_e\rang\}.
\end{aligned}
\]
设最小费用为 \(c\), 对应的解集 \(\{x_{0..n}\}\). 注意此时可能有 \(x_0\neq0\), 所以需要令 \(x_i\gets x_i-x_0\) 并得到实际的最小费用 \(c'\), 则 \(\sum_{i=1}^ne_i+c'\) 就是答案, \(\{x_{0..n}\}\) 的差分就是方案. 复杂度为 \(\mathcal O(\text{Dinic}(n,5n))\).
不过 ... 求这个解集 \(\{x_{0..n}\}\) 并不太容易. 神 crashed 称可以将残量网络上的 \(f_{uv}\) 对偶回原线规, 然后根据互松弛定理得到关于 \(x\) 的取等条件, 最后建差分约束解出 \(x\). 现在你知道我没有写代码的原因啦!
\(\mathscr{Code}\)
放一下传统建图的代码, 直接读建图部分不难理解. 复杂度是一样的.
/*+Rainybunny+*/
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
typedef long long LL;
typedef std::pair<int, LL> PIL;
typedef std::pair<LL, int> PLI;
#define fi first
#define se second
const int MAXN = 1e3;
int n, k, ms, me, s[MAXN + 5], e[MAXN + 5];
namespace FG {
// #define POSITIVE_FLAG // determined if spfa is necessary.
const int MAXND = MAXN + 1, MAXEG = MAXN * 2 + 1;
const LL LINF = 1ll << 60;
int S, T, ecnt = 1, head[MAXND + 5], curh[MAXND + 5];
LL dis[MAXND + 5], hgt[MAXND + 5];
struct Edge { int to, flw, cst, nxt; } graph[MAXEG * 2 + 5];
bool instk[MAXND + 5];
inline void link(const int s, const int t, const int f, const int c) {
// printf("%d %d %d,%d\n", s, t, f, c);
graph[++ecnt] = { t, f, c, head[s] }, head[s] = ecnt;
graph[++ecnt] = { s, 0, -c, head[t] }, head[t] = ecnt;
}
#ifndef POSITIVE_FLAG
inline bool spfa() {
static std::queue<int> que;
static bool inq[MAXND + 5];
rep (i, S, T) dis[i] = LINF;
dis[S] = 0, que.push(S);
while (!que.empty()) {
int u = que.front(); que.pop(), inq[u] = false;
for (int i = head[u], v; i; i = graph[i].nxt) {
if (graph[i].flw && dis[v = graph[i].to] > dis[u] + graph[i].cst) {
dis[v] = dis[u] + graph[i].cst;
if (!inq[v]) inq[v] = true, que.push(v);
}
}
}
return dis[T] != LINF;
}
#endif
inline bool dijkstra() {
static std::priority_queue<PLI, std::vector<PLI>, std::greater<PLI>> heap;
rep (i, S, T) hgt[i] += dis[i], dis[i] = LINF;
heap.emplace(dis[S] = 0, S);
while (!heap.empty()) {
PLI p(heap.top()); heap.pop();
if (p.fi != dis[p.se]) continue;
for (int i = head[p.se], v; i; i = graph[i].nxt) {
LL d = p.fi + graph[i].cst - hgt[v = graph[i].to] + hgt[p.se];
if (graph[i].flw && d < dis[v]) heap.emplace(dis[v] = d, v);
}
}
return dis[T] != LINF;
}
inline PIL augment(const int u, int iflw) {
if (u == T) return { iflw, 0 };
PIL ret(0, 0); instk[u] = true;
for (int &i = curh[u], v; i; i = graph[i].nxt) {
if (graph[i].flw && !instk[v = graph[i].to]
&& dis[v] == dis[u] + graph[i].cst - hgt[v] + hgt[u]) {
PIL t(augment(v, std::min(iflw, graph[i].flw)));
graph[i].flw -= t.fi, graph[i ^ 1].flw += t.fi;
ret.fi += t.fi, iflw -= t.fi;
ret.se += t.se + 1ll * graph[i].cst * t.fi;
if (!iflw) break;
}
}
if (ret.fi) instk[u] = false;
return ret;
}
inline PIL dinic() {
PIL ret(0, 0);
#ifdef POSITIVE_FLAG
while (dijkstra()) {
#else
for (spfa(); dijkstra();) {
#endif
rep (i, S, T) curh[i] = head[i], instk[i] = false;
PIL t(augment(S, 0x3f3f3f3f));
ret.fi += t.fi, ret.se += t.se;
}
return ret;
}
} // namespace FG.
int main() {
scanf("%d %d %d %d", &n, &k, &ms, &me);
rep (i, 1, n) scanf("%d", &s[i]);
rep (i, 1, n) scanf("%d", &e[i]);
FG::S = 0, FG::T = n + 1;
rep (i, 1, n) FG::link(i, std::min(i + k, n + 1), 1, s[i] - e[i]);
rep (i, 1, k - 1) FG::link(i, i + 1, k - ms, 0);
rep (i, k, n) FG::link(i, i + 1, k - ms - me, 0);
FG::link(FG::S, 1, k - ms, 0);
LL ans = 0;
rep (i, 1, n) ans += s[i];
printf("%lld\n", ans - FG::dinic().se);
rep (i, 1, n) putchar("ES"[FG::graph[i << 1].flw]);
putchar('\n');
return 0;
}
Solution -「NEERC 2016」Delight for a Cat 的一个尝试的更多相关文章
- Solution -「ZJOI 2016」「洛谷 P3352」线段树
\(\mathcal{Descrtiption}\) 给定 \(\{a_n\}\),现进行 \(m\) 次操作,每次操作随机一个区间 \([l,r]\),令其中元素全部变为区间最大值.对于每个 \ ...
- Solution -「CERC 2016」「洛谷 P3684」机棚障碍
\(\mathcal{Description}\) Link. 给一个 \(n\times n\) 的网格图,每个点是空格或障碍.\(q\) 次询问,每次给定两个坐标 \((r_1,c_1), ...
- Solution -「NOI 2016」「洛谷 P1587」循环之美
\(\mathcal{Description}\) Link. 给定 \(n,m,k\),求 \(x\in [1,n]\cap\mathbb N,y\in [1,m]\cap \mathbb ...
- Solution -「SDOI 2016」「洛谷 P4076」墙上的句子
\(\mathcal{Description}\) Link. (概括得说不清话了还是去看原题吧 qwq. \(\mathcal{Solution}\) 首先剔除回文串--它们一定对答案产 ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「简单 DP」zxy 讲课记实
魔法题位面级乱杀. 「JOISC 2020 Day4」治疗计划 因为是不太聪明的 Joker,我就从头开始理思路了.中途也会说一些和 DP 算法本身有关的杂谈,给自己的冗长题解找借口. 首先,治疗方案 ...
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
- Solution -「CF 1342E」Placing Rooks
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...
随机推荐
- springboot:调用接口返回的数据乱码解决
从git拉下来项目后,运行服务,启动正常,但是使用swagger和postman调用服务接口出现乱码问题 每一个接口返回的数据是乱码,但是控制台打印的日志都是正常的,后续发现数据的返回类型不是常见的a ...
- 如何获取Flume连接HDFS所需要的包
在学习Hadoop工具中的Flume时,有的小伙伴会遇到这句话: "Flume要想将数据输出到HDFS,必须持有Hadoop相关jar包" 然后小伙伴就懵逼了,这些包要去什么地方来 ...
- Windows通过修改注册表设置系统默认浏览器
前段时间有个程序要求获取系统的默认浏览器,baidu.Google了好久,后又结合procmon.exe跟踪浏览器打开web页面的注册表操作信息,找到了最终的位置,这里做一个总结.亲测win10多个浏 ...
- games101_Homework6
实现 Ray-Bounding Volume 求交与 BVH 查找 在本次编程练习中,你需要实现以下函数: • IntersectP(const Ray& ray, const Vector3 ...
- games101_Homework0
给定一个点 P=(2,1), 将该点绕原点先逆时针旋转 45 ◦,再平移 (1,2), 计算出 变换后点的坐标(要求用齐次坐标进行计算). 作业解答: #include<cmath> #i ...
- Docker制作私有镜像仓库
构建私有仓库 启动Docker Registry,使用Docker官方提供的Registry镜像就可以搭建本地私有镜像仓库,具体指令如下. docker run -d -p 5000:5000 --r ...
- 6. jenkins触发器
常用的触发器 Jenkins内置4种构建触发器 触发远程 构建其他工程构建后触发(Build after other projects are build) 定时构建(Build periodical ...
- 子组件监听props中的值,监听不到旧值的相关问题
昨天,在项目中做一个功能,一个tab切换,点击其中一个tab的时候,调用组件中的查询方法,切只调用一次.再次切换的时候不再调用. 我的做法是: 在父组件中创建一个变量,初始化data中设为0,在点击t ...
- Element-Plus表格:Table自定义合并行数据的最佳实践
" 知行合一 " -- 王阳明 在开发项目中,我们时常会用到表格,许多需求可能会要求自定义特定的行或列. 接下来,我们将探讨在实际开发中如何应对这一挑战. 本文案例采用的技术: 名 ...
- Reviewbot 开源 | 这些写 Go 代码的小技巧,你都知道吗?
Reviewbot 是七牛云开源的一个项目,旨在提供一个自托管的代码审查服务, 方便做 code review/静态检查, 以及自定义工程规范的落地. 自从上了 Reviewbot 之后,我发现有些 ...