摆渡线路摆渡线路摆渡线路
题目
某市的 M 公园中有一个近乎圆形的湖,有100 个主要景点分布在湖边,为了方便游客,公园在一些景点之间开设了直通的摩托飞艇摆渡的项目一来减少游客在景点到景点之间所花的时间,二来也可以让游客体验一下惊险刺激的摩托飞艇
果然摩托飞艇摆渡项目大为成功,为了充分满足游客需要,摆渡线路越来越多。不料随着线路的增加,危险性也随之增加。如果两个摆渡线路之间有交叉(如上图),在这两个线路上的飞艇一旦发生碰撞,后果将不堪设想
公园的管理层近日做出决定,本着安全第一的原则,在这个湖上取消一些线路,使剩下的任意两条线路在行驶阶段(即不考虑码头)不交叉
同时,考虑到经济效益,他们要求被取消的线路数最小,即保留尽量多的线路。他们希望你能够帮助他们算一算最多可以保留多少条线路
输入
从文件 line.in 中读入数据,文件的第一行为NNN (1=<N<=10000)(1=<N<=10000)(1=<N<=10000),表示现有的线路数。接下来的 NNN 行,每行有两个 111 至 100100100 的数 a,ba,ba,b,表示 aaa 至 bbb 之间有飞艇往返
显然 aaa 不会等于 bbb,且若 aaa 至 bbb 有线路,则 bbb 至 aaa也必有线路,它们不会同时出现在输入文件中
输出
将结果输出到文件 line.out,文件只有一行,只有一个数,就是保留下来
的线路的最多条数
输入样例
line.in
5
91 31
1 45
27 5
11 65
43 72
输出样例
line.out
3
解题思路
可以把圆展开成链,然后复制一遍
设fi,jf i,jfi,j 为第iii个位置到第jjj个位置的所选弦的数量
那么可以枚举中间点,然后区间DPDPDP
程序如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n, f[2005][2005], x, y, ans = 0;
int main()
{
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
memset(f, 0, sizeof(f));
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d%d", &x, &y);
if (x > y) swap(x, y);
f[x][y] = f[x + 100][y + 100] = 1;
}
for(int l = 2; l <= 100; ++l)
{
for(int i = 1; i <= 200 - l - 1; ++i)
{
int a = i;
int b = i + l - 1;
int t = 0;
for(int k = a + 1 ;k <= b - 1; ++k)
t = max(t, f[a][k] + f[k][b]);
f[a][b] += t;
ans = max(ans, f[a][b]);
}
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
3486

被折叠的 条评论
为什么被折叠?



