【DP】友好城市
阿新 • • 發佈:2018-12-12
題目描述
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;
}