【区间DP】【DG特长生2017】T4摆渡线路
发布日期:2021-05-07 22:47:29 浏览次数:19 分类:精选文章

本文共 2029 字,大约阅读时间需要 6 分钟。

圆上均匀分布100个点的连线保留问题

问题描述

在一个圆上均匀分布了100个点,编号从1到100。给定n对数对(a, b),每对数对代表圆上点a和点b之间有一条连线。任务是要保留尽可能多的连线,使得这些连线互不相交。

解法

我们可以使用动态规划(Dynamic Programming,DP)来解决这个问题。设ans[i][j]表示弧i-j上最多可以保留的连线数。递推公式如下:

$$ ans[i][j] = \max(ans[i][k] + ans[k][j]) + l[i][j] $$

其中,k是弧i-j上的点,l[i][j]是1或0,表示i和j之间是否有连线。

此外,对于弧i-j的长度较大时,我们需要将其分成两个半圆进行处理。具体来说,如果弧i-j的长度超过一定阈值(例如50),则将其分成两部分进行DP计算,然后合并结果。

代码实现

#include 
#include
#include
using namespace std;
int main() {
freopen("line.in", "r", stdin);
freopen("line.out", "w", stdout);
int n, a, b, l[120][120], e, le, ld, ans[120][120], anss = 0;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &a, &b);
l[a][b] = l[b][a] = 1;
}
for (int i = 2; i <= 51; ++i) {
for (int q = 1; q <= 100; ++q) {
e = q + i - 1;
le = (e - 1) % 100 + 1;
for (int d = q; d <= e; ++d) {
ld = (d - 1) % 100 + 1;
if (ans[le][q] < ans[q][ld] + ans[ld][le]) {
ans[le][q] = ans[q][ld] + ans[ld][le];
}
}
ans[le][q] += l[q][le];
if (ans[le][q] > anss) {
anss = ans[le][q];
}
}
}
for (int i = 1; i <= 50; ++i) {
int j = (i + 99) % 100 + 1;
int k = (i + 50) % 100;
int m = (j - 50) % 100 + 1;
if (k > m) {
k = m;
}
ans[i][j] = ans[i][k] + ans[k][j];
if (l[i][j] > 0) {
ans[i][j] += 1;
}
if (l[i+50][k] > 0) {
ans[i][j] += 1;
}
if (l[i][k] > 0) {
ans[i][j] += 1;
}
if (l[i+50][j] > 0) {
ans[i][j] += 1;
}
if (l[i][j] > 0 || l[i+50][k] > 0) {
ans[i][j] += 1;
}
if (ans[i][j] > anss) {
anss = ans[i][j];
}
}
printf("%d", anss);
fclose(stdin);
fclose(stdout);
}

结果输出

程序会读取输入数据,计算每个区间的最优解,并输出最终结果。最终结果即为保留的最多不相交连线的数量。

上一篇:【2017-DG特长生】总结(2021.4.3模拟赛
下一篇:【拓扑排序】【DG特长生2017】工程

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年03月30日 05时58分09秒