【DP】友好城市

题目描述

Palmia国有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。
每对友好城市都向政府申请在河上开辟一条航线连接两个城市,但是由于河上经常起大雾,政府决定避免任意两条航线交叉,以避免事故。请编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航线不相交的情况下,被批准的申请尽量多。

输入

第1行,一个整数N(1<=N<=5000),表示城市数。
第2行到第n+1行,每行两个整数,分别表示南岸和北岸的一对友好城市的坐标。(0<=xi<=10000)

输出

一行,输出一个整数,表示政府所能批准的最多申请数。

输入样例
7
22 4
2 6
10 3
15 12
9 8
17 17
4 2
输出样例
4

思路:

原本以为很难,结果听了一下别人讲,才发现其实还算挺简单的,首先把南岸从小到大快排(北岸一起动),然后求北岸的最长上升子序列的长度。
排序完后是这样:

北岸 南岸
2 6
4 2
9 8
10 3
15 12
17 17
22 4

求北岸的最长上升子序列的长度。

这个排序完后,用的是双重循环(洛谷上只能过一半)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct wah
{
	int a,b;//a是南岸坐标,b是北岸坐标
};
wah a[100002];
int n,f[100002];//f[i]是存以i结尾的最长上升子序列的长度
void qsort(int l,int r)//不要问我为什么把快排敲上了
{
	if(l>=r)return;
	int k=a[(l+r)/2].a;
	int i=l,j=r;
	while(i<=j)
	{
		while(a[i].a<k)i++;
		while(a[j].a>k)j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++;j--;
		}
	}
	qsort(l,j);
	qsort(i,r);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].a,&a[i].b);
	qsort(1,n);
	int maxx=1;//maxx是最长上升子序列的长度
	for(int i=1;i<=n;i++)
	{
		f[i]=1;
		for(int j=i-1;j>=1;j--)
		{
			if(a[j].b<a[i].b && f[j]>=f[i])f[i]=f[j]+1;//如果a[j]的值小于a[i]的值和以j结尾的长度小于以i结尾的长度,就赋为以j结尾的子序列加上a[i].b。
			maxx=max(f[i],maxx);//判断最长子序列的长度
		}
	}
	printf("%d",maxx);
	return 0;
}


这个用的是二分。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct wah
{
	int a,b;
};
wah a[100002];
int n,f[100002],t=1;
void qsort(int l,int r)
{
	if(l>=r)return;
	int k=a[(l+r)/2].a;
	int i=l,j=r;
	while(i<=j)
	{
		while(a[i].a<k)i++;
		while(a[j].a>k)j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++;j--;
		}
	}
	qsort(l,j);
	qsort(i,r);
}
int midd(int m)//二分
{
	int l=1,r=t,mid=(l+r)/2;
	while(l<=r)
	{
		if(m<f[mid])r=mid-1;
		else if(m>f[mid])l=mid+1;
		else return mid;
		mid=(l+r)/2;
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].a,&a[i].b);
	qsort(1,n);
	f[1]=a[1].b;
	for(int i=2;i<=n;i++)
	{
		if(f[t]<a[i].b)
		{
			t++;
			f[t]=a[i].b;
		}
		else
		{
			f[midd(a[i].b)]=a[i].b;
		}
	}
	printf("%d",t);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_wujiajie/article/details/82869789