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

 

你可能感兴趣的:(sequence)