UESTC 1705 The Longest Sequence of Rectangles(DP动态规划)

Description


A rectangle is specified by a pair of coordinates (x1 , y1) and (x2 , y2) indicating its lower-left and upper-right corners (x1 <= x2 and y1 <= y2). For a pair of rectangles, A = ((X_A1, Y_A1), (X_A2, Y_A2)) and B = ((X_B1, Y_B1), (X_B2, Y_B2)), we define A <= B if X_A2<X_B1 and Y_A2<Y_B1. Given a number of rectangles on the plane, you are asked to find the length L of the longest sequence of rectangles (A1, A2, ..., AL) such that A1 <= A2 <= ... <= AL.

Input

The input contains multiple test cases. The first line of the input is an integer T, indicating the number of test cases. Each test case begins with a line containing a single integer n (1 <= n <= 100000), indicating the number of rectangles. Each of the next n lines contains four integers x1, y1, x2, y2 (- 1000000 <= x1 < x2 <= 1000000, -1000000 <= y1 < y2 <= 1000000), indicating the lower left and upper right corners of a rectangle.

Output

For each input test case, output a single integer indicating the length of the longest sequence.

Sample Input

2
3
1 5 2 8
3 -1 5 4
10 10 20 20
2
2 1 4 5
6 5 8 10

Sample Output

2
1

Source

6th BUPT Programming Contest Final

 

类似于最长上升子序列,不过数据量为10W,$O(n^{2})$的算法肯定是行不通的,而普通的最长上升序列二分法的$O(nlogn)$不能直接用于此,需要稍作修改,详见程序。(线段树的$O(nlogn)$也是可以的)

 

#include <cstdio>  
#include <cstring>  
#include <algorithm>  
#include <iostream>  
#include <vector>  
#define MAXN 100010  
      
struct rec  
{  
    int x1,y1,x2,y2;  
    bool operator < (const rec &x) const
    {  
        return x2<x.x2;  
    }  
} a[MAXN];  
      
int T,n,i,j,tmp,ans,k,siz;  
int d[MAXN],g[MAXN];  
std::vector<int> s[MAXN];  
      
int bisearch1(int l,int r,int x)  
{  
    if(x<=a[1].x2) return 0;  
    if(a[r].x2<x) return r;  
    int mid;  
    while(l<r)  
    {  
        mid=(l+r)>>1;  
        if(a[mid].x2<x) l=mid;  
        else r=mid-1;  
        if(l+1==r)  
        {  
            if(a[r].x2<x) return r;  
            else return l;  
        }  
    }  
    return l;  
}  
      
int bisearch2(int l,int r,int x)  
{  
    if(x<=g[1]) return 0;  
    if(g[r]<x) return r;  
    int mid;  
    while(l<r)  
    {  
        mid=(l+r)>>1;  
        if(g[mid]<x) l=mid;  
        else r=mid-1;  
        if(l+1==r)  
        {  
            if(g[r]<x) return r;  
            else return l;  
        }  
    }  
    return l;  
}  
      
int main()  
{  
    while(scanf("%d",&T)!=EOF)  
        while(T--)  
        {  
            scanf("%d",&n);  
            for(i=1;i<=n;++i)  
            {  
                scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);  
                s[i].clear();  
                d[i]=1;  
            }  
            std::sort(a+1,a+n+1);  
            memset(g,127,sizeof(g));  
            for(i=2;i<=n;++i)  
            {  
                tmp=bisearch1(1,i-1,a[i].x1);  
                if(tmp!=0) s[tmp].push_back(i);  
            }  
            for(i=1,ans=0;i<=n;++i)  
            {  
                if(a[i].y2<g[d[i]]) g[d[i]]=a[i].y2;  
                siz=s[i].size();  
                for(j=0;j<siz;++j)  
                {  
                    k=bisearch2(1,i,a[s[i][j]].y1);  
                    d[s[i][j]]=k+1;  
                }  
                if(d[i]>ans) ans=d[i];  
            }  
            printf("%d\n",ans);  
        }  
    return 0;  
}
View Code

 

posted @ 2013-06-04 10:18  Oyking  阅读(218)  评论(0编辑  收藏  举报