摆渡线路(特长生2017)【DP】

>Description

有一个周长为100个单位长度的圆,其中给出 n n n 条弦,每条弦的两个端点已知
求最多可以有多少条弦同时存在且两两不相交


>解题思路

常规操作,将这个圆拆成一条链
然后可以进行DP, 设 f i , j f_{i,j} fi,j 为从 i i i j j j 合法的最多弦数,这样可以使得弦两两不相交
状态转移方程: f i , j = m a x ( f i , t + f t , j + p i , j ) f_{i,j}=max(f_{i,t}+f_{t,j}+p_{i,j}) fi,j=max(fi,t+ft,j+pi,j)
p i , j p_{i,j} pi,j表示是否有端点为 i i i j j j 的一条弦)


>代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 10010
using namespace std;

int n, x, y, f[200][200];
bool p[200][200];

int main()
{
    
    
	freopen ("line.in", "r", stdin);
	freopen ("line.out", "w", stdout);
	
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++)
	{
    
    
		scanf ("%d%d", &x, &y);
		p[x][y] = p[y][x] = 1;
	}
	for (int k = 2; k <= 100; k++) //长度
	  for (int i = 1; i <= 100 - k + 1; i++) //起点
	  {
    
    
	  	int j = i + k - 1; //终点
	  	if (k == 2) {
    
    f[i][j] = p[i][j]; continue;}
	  	for (int t = i; t <= j; t++)
	  	  f[i][j] = max (f[i][j], f[i][t] + f[t][j]);
	  	f[i][j] += p[i][j];
	  }
	printf ("%d", f[1][100]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43010386/article/details/115415677