<Discription>
PALMIA国家被一条河流分成南北两岸,南北两岸上各有N个村庄。北岸的每一个村庄有一个唯一的朋友在南岸,且他们的朋友村庄彼此不同。每一对朋友村庄想要一条船来连接他们,他们向政府提出申请以获得批准。由于河面上常常有雾,政府决定禁止船只航线相交(如果相交,则很可能导致碰船)。你的任务是编写一个程序,帮助政府官员决定比准哪些船只航线,使得不相交的航线数目最大。
<input>
输入有几组数据组成。每组数据的第一行有2个整数X,Y,中间有一个空格隔开,X代表PALMIA河的长度(10<=X<=6000),Y代表河的宽度(10<=Y<=100)。第二行包含整数N,表示分别坐落在南北两岸上的村庄的数目(1<=N<=5000)。在接下来的N行中,每一行有两个非负整数C,D,由一个空格隔开,分别表示这一对朋友村庄沿河岸与PALMIA河最西边界的距离(C代表北岸的村庄,D代表南岸的村庄),不存在同岸又同位置的村庄。最后一组数据的下面仅有一行,是两个0,也被一行空格隔开。
<output>
对输入的每一组数据,输出最大可能满足上述条件的航线的数目。
<input example>
30 4
7
22 4
2 6
10 3
15 12
9 8
17 17
4 2
0 0
<output example>
4
<问题分析>
两条线路相交的条件为C1>C2,D1<D2或者C1<C2,D1>D2。若不相交,则有C1<D1,C2<D2。
由此先对一边的村子位置进行排序,再根据序号,找出另一边村子的最长非降序列。
//ship #include <stdio.h> #include <algorithm> #include <stdlib.h> struct TP { int p1; int p2; }; int cmp(const void *t1,const void *t2) { struct TP *t11,*t22; t11=(TP *)t1; t22=(TP *)t2; return t11->p1>t22->p1; } int main() { int x,y,n,i,j,val[5001]; struct TP tp[5001]; while(true) { scanf("%d %d",&x,&y); if(!x&&!y) break; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d %d",&(tp[i].p1),&(tp[i].p2)); } for(i=0;i<n;i++) val[i]=1; qsort(tp,n,sizeof(tp[0]),cmp); /* for(i=1;i<n;i++) { printf("%d ",tp[i].p1); } printf(" "); */ for(i=1;i<n;i++) { for(j=0;j<i;j++) { if(tp[i].p1>=tp[j].p1&&tp[i].p2>=tp[j].p2) if(val[i]<val[j]+1) val[i]=val[j]+1; } } j=0; for(i=0;i<n;i++) { if(j<val[i])j=val[i]; //printf("%d ",val[i]); } //printf(" "); printf("%d ",j); } return 0; }