1 /*题意:有n个矩形,用长和宽表示,如果一个的长和宽都比另一个小,那么这个嵌放在另一个中
2 所以先对w从大到小排序,w一样的按h从小到大排序,那么就从后面的箱子往前找,只要前面找到一个人h比自己大的就放入c[j]=p[i].h;
3 否则如果自己的h比前面的都大,那么必定询问到c所存的递增序列的长度+1处,那么个数加1,长度加1,把此事的h放在在c的末端
4 这个过程和最大递增子序列的找值过程类似,但是并不是求最长递增,只是利用这个过程,所以二分查找稍微有些改变,如果还是按照
5 最长公共子序列的二分查找,那么h相同的会被覆盖掉比如数据1 1 1 1 2 2 2 2,其中一个2 2会被另一个2 2覆盖掉,导致结果为3*/
6
7 #include<stdio.h>
8 #include<string.h>
9 #include<algorithm>
10 using namespace std;
11 struct node
12 {
13 int w,h;
14 }p[20010];
15 int cmp(const node a,const node b)
16 {
17 if(a.w==b.w) return a.h<b.h;
18 return a.w>b.w;
19 }
20 int find(int *p,int len,int n)
21 {
22 int l=0,r=len;
23 int mid=(l+r)/2;
24 while(l<=r)
25 {
26 if(n>=p[mid]) l=mid+1;
27 else r=mid-1;
28 mid=(l+r)/2;
29 }
30 /*while(l<=r)//最长递增子序列的二分查找
31 {
32 if(n>p[mid]) l=mid+1;
33 else if(n<p[mid]) r=mid-1;
34 else return mid;//递增不应许有两个高度一样的,所以要覆盖
35 mid=(l+r)/2;
36 }*/
37 return l;
38 }
39 int main()
40 {
41 int i,j,k,n,m;
42 int T;
43 int c[20010];
44 scanf("%d",&T);
45 while(T--)
46 {
47 memset(c,0,sizeof(c));
48 scanf("%d",&n);
49 for(i=0;i<n;i++)
50 {
51 scanf("%d%d",&p[i].w,&p[i].h);
52 }
53 sort(p,p+n,cmp);
54 int len=1;
55 c[0]=-1;
56 c[1]=p[0].h;
57 for(i=1;i<n;i++)
58 {
59 j=find(c,len,p[i].h);
60 c[j]=p[i].h;
61 if(j==len+1) len++;
62 }
63 printf("%d\n",len);
64 }
65 return 0;
66 }