关闭

sgu 199 Beautiful People dp

420人阅读 评论(0) 收藏 举报
分类:

       在网上看了个思路,按x递增排序,x相同按y递减排序..然后求一个y的最长上升序列就行..这思路太神了,因为y在x相同的组内是递减的,所以找到一个更大的时,x一定更大..由于长度有10W,求上升序列的时候需要维护一个单调栈+二分,上升序列的长度就是栈的最大深度。路径没有特殊的要求,可行的都可以,每个点记录一下上一个的位置,最后递归或者循环一下输出就可以。

        

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=140000;
int n,p,q;
int stack[maxn];
int top;
int pre[maxn];
struct node
{
    int x,y,idx;
    bool operator<(const node& p)const
    {
       if (x!=p.x) return x<p.x;
       return y>p.y;
    }
    node(){}
    node(int a,int b,int c)
    {
        x=a;
        y=b;
        idx=c;
    }
}a[maxn];

void print(int k)
{
    if (k==-1) return;
    print(pre[k]);
    printf("%d ",a[k].idx);
}
int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for (int i=0; i<n; i++)
    scanf("%d%d",&a[i].x,&a[i].y),a[i].idx=i+1;
    sort(a,a+n);
    memset(stack,0,sizeof stack);
    memset(pre,-1,sizeof pre);

    top=0;
    top++;
    stack[0]=-1;
    stack[top]=0;
    pre[0]=-1;
    int l,r,m;
    for (int i=1; i<n; i++)
    {
        if (a[i].y>a[stack[top]].y)
        {

            top++;
            stack[top]=i;
            pre[i]=stack[top-1];

        }
        else
        {
            l=1; r=top;
            while (l<r)
            {
                m=(l+r)>>1;
                if (a[stack[m]].y<a[i].y) l=m+1;
                else r=m;
            }
            stack[l]=i;
            pre[i]=stack[l-1];
        }
    }
    printf("%d\n",top);
    print(stack[top]);
    puts("");
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:132537次
    • 积分:3727
    • 等级:
    • 排名:第8692名
    • 原创:250篇
    • 转载:0篇
    • 译文:0篇
    • 评论:35条
    文章分类
    最新评论