hunnu 11182#最长非递减子序列

Xujie卖车
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB
Total submit users: 1, Accepted users: 1
Problem 11182 : No special judgement
Problem description
  临近毕业,sxj_program(Xujie)打算卖掉他的二手自行车,但他却不知道应该卖多少钱才合适。所以他打算研究一种方法来评估自行车的价格。

下图是Xujie的宝马(现在可能是34手了……)。看得出来,Xujie很爱护他的宝马,刹车,车座和轮胎都保养得很好,只是车轴掉了几根。所 以他决定根据剩下的车轴来评估价格。作为一名NKU ACMerXujie不想简单地将价格与车轴的数量挂钩,而是根据"knot""knot"的含义是由车轴组成的集合,这个集合中的每根车轴两两相 交。为了简化这个问题,Xujie将自行车的轮子看成一个圆,而每根车轴看成圆上的一条弦。

因为快要毕业了,Xujie想要好好地吃喝玩乐一把,顺便找找妹子,没时间解决这个问题,所以他想请你来帮帮忙(当然,Xujie已经毕业了,车也 卖出去了,但是他还是想知道根据这种方法评估出来的价格)Xujie会给你一个车轮(圆和圆上的一些弦),请你告诉Xujie最大的"knot"的大小 是多少,一个"knot"的大小为它的元素个数。

Input
  输入的第一行是一个正整数N(N<=2000),表示车轴的数量。接下来的N行,每行输入两个整数i,j(1<=i,j<=2*N).表示该车轴由圆上的i点连接到j点。

假定从圆上某点开始,点1,2,...按顺时针排列。注意,因为可能会有一些车轴交于圆上的同一点,这种情况下的点数会小于2*N.

Output
  输出最大的"knot"的大小。

Sample Input
31 32 56 4
Sample Output
2
Judge Tips
  

样例如图所示,最多有两根车轴彼此相交,所以答案为2

 

附加样例:

Sample Input:

4
1 6
2 5
3 5
4 7

Sample Output:

3



Problem Source
  NKPC8


将每条弦看成区间(l,r)(l < r),


则满足条件的集合是l 和 r分别非递减,又相交的条件易知

处理:先按l排序,l相同按rpaixu

枚举每个起始区间p,在与p相交的所有区间中求出一个r的最长子序列

例2

{(1,6),(4,7)},{(2,5),(3,5),(4,7)}

#include 
#include 
using namespace std;
#define N 2002

struct node
{
    int l,r;
    void input()
    {
        scanf("%d%d",&l,&r);
        if(l > r)
            swap(l,r);
    }
}pt[N];

int n,a[N];
bool cmp(node a,node b)
{
    if(a.l == b.l)
        return a.r < b.r;
    return a.l < b.l;
}
//返回第一个比x大的数
//最长非递减序列
int bs(int r,int x)
{
    int l = 0,mid;
    while(l <= r)
    {
        mid = (l + r) >> 1;
        if(a[mid] > x)
            r = mid - 1;
        else
            l = mid + 1;
    }
    return l;
}
int main()
{
    scanf("%d",&n);
    int i,j;
    for(i = 0; i < n; ++i)
        pt[i].input();
    sort(pt, pt + n,cmp);
    int res = -1,top = 0,p;
    for(i = 0; i < n; ++i)
    {
        top = 0;
        a[top] = pt[i].r;
        for(j = i + 1; j < n; ++j)
        {
            if(pt[j].l > pt[i].r)
                break;

            if(pt[j].r >= pt[i].r)
            {
                p = bs(top,pt[j].r);
                if(p > top)
                    top = p;
                a[p] = pt[j].r;
            }
        }
        ++top;
        if(top > res)
            res = top ;
    }
    printf("%d\n",res);
    return 0;
}




你可能感兴趣的:(DP)