Rainbow Bracket Sequence

news/2024/9/20 2:31:25/文章来源:https://www.cnblogs.com/qjbqjb/p/18419473

The 2024 ICPC Asia East Continent Online Contest (I)

题意

构造长度为 \(2n\) 的合法括号序列。

对于每个左括号在的位置 \(i\), 都有颜色 \(c_i\) 和价值 \(v_i\)

左括号颜色视为所在位置颜色, 价值同理。

对于每个颜色,满足左括号为该颜色的个数 \(\geq l_i\)

求满足以上条件下,最大左括号的价值和。

\(n \leq 100, m \leq n, v_i \leq 10^9\)

做法

是费用流,关键在于建模。

  • 保证合法括号序列

首先构建点 \(1 \dots 2n\) 表示所有括号序列。

把原点 \(S\) 连向所有奇数点,即 \(S \to 1, S\to 3, \dots, S \to 2n - 1\)

流量,边权 为 \((1, 0)\), 即表示左括号在这些点。

同时,对 \(i + 1 \to i\), 连 \((+\infty, 0)\), 表示左括号可以向左移动。

可以发现, 这样构造出来的括号序列总是合法的, 总能保证左右括号匹配且任意前缀左括号个数大于等于右括号个数。

  • 颜色限制

首先, 每个位置 \(i\) 连向对应颜色 \(c_i\), 边权为 \(-v_i\), 流量为 \(1\)

为了保证颜色 \(i\)\(l_i\) 个, 连 \(c_i \to T\) 时, 流量为 \(l_i\), 边权为 \(-\infty\),(可以是极小的数 \(-10^{13}\)) 表示一定要选。

对于超过 \(l_i\) 的部分,连 \(c_i \to T\)\((\infty, 0)\) 的边, 表示可以选。

  • 跑最小费用最大流即可

求得 \(\lfloor\frac{\text{mincost}}{-10^{13}}\rfloor = \sum l_i\), 即有解,

最后的答案为 \(\text{mincost} \mod (-10^{13})\)

code

#include<bits/stdc++.h>
using namespace std;
using ll = long long;  
const int N = 10100;
const ll INF = 1e13; int n, m, s, t;
int col[N], val[N], l[N]; struct edge {int v, len, next;ll w;  
} e[N];
int cnt;
int first[N], cur[N]; void add(int u, int v, int len, ll w) {++ cnt;e[cnt].v = v;e[cnt].len = len; e[cnt].w = w; e[cnt].next = first[u];first[u] = cnt; 
}
void Add(int u, int v, int len, ll w) {add(u, v, len, w); add(v, u, 0, -w); 
} 
void init() {cnt = 1; s = 2 * n + m + 1, t = 2 * n + m + 2; for (int i = 1; i <= t; i ++)first[i] = 0;   
}bool vis[N];
ll dis[N];  
bool bfs() {memcpy(cur, first, sizeof(first)); for (int i = 1; i <= t; i ++)vis[i] = 0, dis[i] = INF;queue<int> q; q.push(s); dis[s] = 0; while (!q.empty()) {int u = q.front(); q.pop();vis[u] = 0; for (int i = first[u]; i; i = e[i].next) {int v = e[i].v, len = e[i].len;ll w = e[i].w; if (!len || dis[v] <= dis[u] + w) continue;dis[v] = dis[u] + w;if (!vis[v]) {q.push(v),vis[v] = 1; }}}return dis[t] != INF; 
}
ll cost; 
int dfs(int u, int flow) {if (u == t) {return flow; }int ans = 0; vis[u] = 1;for (int &i = cur[u]; i; i = e[i].next) {int v = e[i].v, len = e[i].len; ll w = e[i].w; if (vis[v] || dis[v] != dis[u] + w || !len) continue; int out = dfs(v, min(len, flow));if (out) {ans += out; cost += 1ll * out * w; e[i].len -= out;e[i ^ 1].len += out; flow -= out; } }return ans; 
}
ll dinic() {ll ans = 0; while (bfs()) {cost = 0; dfs(s, 0x7fffffff);ans += cost;}return ans; 
}void solve() {cin >> n >> m; init(); int suml = 0; for (int i = 1; i <= m; i ++)cin >> l[i], suml += l[i];for (int i = 1; i <= 2 * n; i ++)	cin >> col[i]; for (int i = 1; i <= 2 * n; i ++)cin >> val[i]; for (int i = 1; i <= 2 * n; i += 2)Add(s, i, 1, 0); for (int i = 1; i <= 2 * n - 1; i ++) Add(i + 1, i, 0x7fffffff, 0); for (int i = 1; i <= 2 * n; i ++)Add(i, 2 * n + col[i], 1, - val[i]); for (int i = 1; i <= m; i ++) {Add(2 * n + i, t, l[i], -INF);Add(2 * n + i, t, 0x7fffffff, 0); }ll cost = dinic();if (cost / (-INF) == suml) {cout << (-cost) % INF << endl;} elsecout << -1 << endl;
} int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0); int T;cin >>T;while (T --)solve(); return 0;
}

最后 %%%klii , 感谢他的教导。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/799573.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

字符编码发展史2 — ISO-8859-N

2.2. 第二个阶段 本地化2.2.1. ANSI 2.2.2. ISO/IEC 8859-N2.2.2.1. 什么是ISO/IEC 8859-N? 2.2.2.2. ISO 8859-1的编码表上一篇《字符编码发展史1 — ASCII和EASCII》我们讲解了字符编码的起源ASCII和EASCII。本篇我们将继续讲解字符编码的第二个发展阶段中的ISO 8859-N。 2.…

?

CF1194G 在外层枚举\(x\)和\(y\),令\(x=x\times t,y=y\times t\),且\(x\times t\)十进制包含\(x\),\(y\)同理。 因为有进位,从低位向高位dp。 设\(f[T][0/1][0/1][i][j][0/1][0/1]\)表示处理到第T位,在当前这些为中\(x\times t\)是否大于\(n\),\(y\times t\)是否大于\(n\),…

网络补充

1. 网卡配置(ip,dns)目标:修改网卡的名字为eth0. 修改网卡配置文件,ip,dns,网关,子网掩码.(物理机,虚拟机(私有云)) 公有云自动获取即可,服务器数量巨大自动获取.1.1 网卡命名 结论: 工作有需求的时候再去修改. 做好记录,后面使用的时候参考即可. # 网卡命名规则: ens33 ensxxx…

在idea中使用mysql失败

在idea中测试mysql显示失败idea方面视图 - 工具窗口 - 数据库 或者右边有图标直接点开新建 - 数据源 - mysql名称 - 用户(root) - 密码 - 测试连接如果测试连接有切换相关提示直接点击, 如果出绿色对勾就成功了 到这里本可以结束了, 但是我最开始做的时候这个流程没有成功 以防…

Pyhton调用R语言rpy2包概要

随着深度学习、大数据和AI的发展,Python的热度持续上升,引发了关于选择Python还是R的讨论。作为数据分析工具,两者各有优缺点。在特定领域,如生态学,R仍被广泛应用,而Python则更多用于日常办公自动化,如批量处理文档和Excel。由于数据处理占用了我们大量时间,很多人希望…

自动驾驶运动规划学习_碰撞检测算法_GJK

自动驾驶运动规划学习:碰撞检测算法:GJK Gilbert–Johnson–Keerthi(GJK)算法,是一种用于检测两个凸集是否重叠的高效算法,并且可以得到两个凸集的最小距离.1.4.1 GJK算法原理1.4.1.1 闵可夫斯基差(Minkowski Difference)1.4.1.3 凸性 在二维空间中,如果一个凸集包含原点,…

设计模式之——代理模式

代理模式 前言: 我们一般在租房子时会去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做;再比如我们打官司需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们的想法;再比如在淘宝上面买东西,你使用支付宝平台…

一文搞定WeakHashMap

写在前面 在缓存场景下,由于内存是有限的,不能缓存所有对象,因此就需要一定的删除机制,淘汰掉一些对象。这个时候可能很快就想到了各种Cache数据过期策略,目前也有一些优秀的包提供了功能丰富的Cache,比如Google的Guava Cache,它支持数据定期过期、LRU、LFU等策略,但它…

P2710 数列/P2042 [NOI2005] 维护数列

题意(以 P2710 为例)思路 使用 FHQ-Treap 进行求解,清晰明了。对于 insert,先将要插入的数建成一棵树,然后将这棵树放入 FHQ-Treap 中。 对于 delete,将要删除的树分离出来,然后把剩下的部分合并即可,将删除的树的树根丢到废弃节点的栈中以备以后使用(节约空间,不然 …

扩展分析C语言单双引号、反斜杠与注释

目录注释奇怪的注释C风格的注释无法嵌套一些特殊的注释注释的规则建议反斜杠\反斜杠有续行的作用,但要注意续行后不能添加空格回车也能起到换行的作用,那续行符的意义在哪?反斜杠的转义功能单引号和双引号字面值,字符串,字符,字符变量的大小为什么sizeof(1)的大小是4 ?char…

扩展分析单双引号、反斜杠与注释

目录注释奇怪的注释C风格的注释无法嵌套一些特殊的注释注释的规则建议反斜杠\反斜杠有续行的作用,但要注意续行后不能添加空格回车也能起到换行的作用,那续行符的意义在哪?反斜杠的转义功能单引号和双引号字面值,字符串,字符,字符变量的大小为什么sizeof(1)的大小是4 ?char…

C----函数递归之反汇编

环境 win10 vc6.0 debug 代码 关于求阶层问题:n!=n(n-1)!;(n-1)! = (n-1)(n-2)! 例如5!=5(4)! 4!=43! 3!=32! 2!=21 函数递归的出口是1,所以函数递归最重要的条件是去寻找递归的出口 int fun(int i) {int sum = 0;if (i == 1){return 1;}else{sum = i*fun(i-1);}return sum …