【区间DP】摆渡线路

摆渡线路摆渡线路线


题目

某市的 M 公园中有一个近乎圆形的湖,有100 个主要景点分布在湖边,为了方便游客,公园在一些景点之间开设了直通的摩托飞艇摆渡的项目一来减少游客在景点到景点之间所花的时间,二来也可以让游客体验一下惊险刺激的摩托飞艇
果然摩托飞艇摆渡项目大为成功,为了充分满足游客需要,摆渡线路越来越多。不料随着线路的增加,危险性也随之增加。如果两个摆渡线路之间有交叉(如上图),在这两个线路上的飞艇一旦发生碰撞,后果将不堪设想
公园的管理层近日做出决定,本着安全第一的原则,在这个湖上取消一些线路,使剩下的任意两条线路在行驶阶段(即不考虑码头)不交叉
同时,考虑到经济效益,他们要求被取消的线路数最小,即保留尽量多的线路。他们希望你能够帮助他们算一算最多可以保留多少条线路


输入

从文件 line.in 中读入数据,文件的第一行为NNN (1=<N<=10000)(1=<N<=10000)1=<N<=10000,表示现有的线路数。接下来的 NNN 行,每行有两个 111100100100 的数 a,ba,ba,b,表示 aaabbb 之间有飞艇往返
显然 aaa 不会等于 bbb,且若 aaabbb 有线路,则 bbbaaa也必有线路,它们不会同时出现在输入文件中

输出

将结果输出到文件 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值