zoukankan      html  css  js  c++  java
  • ACdream 1216 (ASC训练1) Beautiful People(DP)

    题目地址:http://acdream.info/problem?

    pid=1216

    这题一開始用的是线段树。后来发现查询的时候还须要DP处理。挺麻烦。。也就不了了之了。。后来想到,这题事实上就是一个二维的最长上升子序列。

    要先排序,先按左边的数为第一keyword进行升序排序。再按右边的数为第二keyword进行降序排序。这种话,第一keyword同样的的肯定不在一个同一个上升子序列中。然后仅仅对第二keyword进行复杂度为O(n*logn)的DP,找出最长上升序列,然后处理前驱,并输出就可以。

    代码例如以下:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <stdlib.h>
    #include <math.h>
    #include <ctype.h>
    #include <queue>
    #include <map>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    #define LL long long
    struct node
    {
        int x, y, num;
    }fei[110000];
    int cmp(node x, node y)
    {
        if(x.x==y.x)
            return x.y>y.y;
        return x.x<y.x;
    }
    int a[110000], d[110000], pre[110000], len, b[110000];
    int bin_seach(int x)
    {
        int low=0, high=len, mid, ans;
        while(low<=high)
        {
            mid=low+high>>1;
            if(a[mid]>=x)
            {
                high=mid-1;
                ans=mid;
            }
            else
            {
                low=mid+1;
            }
        }
        return ans;
    }
    int main()
    {
        int n, i, j, pos, cnt;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=0;i<n;i++)
            {
                scanf("%d%d",&fei[i].x,&fei[i].y);
                fei[i].num=i+1;
            }
            sort(fei,fei+n,cmp);
            len=1;
            a[1]=fei[0].y;
            d[0]=-1;
            d[1]=0;
            memset(pre,-1,sizeof(pre));
            for(i=1;i<n;i++)
            {
                if(fei[i].y>a[len])
                {
                    a[++len]=fei[i].y;
                    pre[i]=d[len-1];
                    d[len]=i;
                }
                else
                {
                    pos=bin_seach(fei[i].y);
                    a[pos]=fei[i].y;
                    pre[i]=d[pos-1];
                    d[pos]=i;
                }
            }
            printf("%d
    ",len);
            cnt=0;
            /*for(i=0;i<n;i++)
            {
                printf("%d ",fei[i].num);
            }
            puts("");*/
            for(i=d[len];i!=-1;i=pre[i])
            {
                b[cnt++]=fei[i].num;
                //printf("%d
    ",i);
            }
            for(i=0;i<cnt-1;i++)
                printf("%d ",b[i]);
            printf("%d
    ",b[cnt-1]);
        }
        return 0;
    }
    


  • 相关阅读:
    tomcat feign rocketmq 最大线程数
    rocketmq
    使用docker在linux上安装oracle数据库
    dnf 腾讯 解人脸
    记一次mysql慢查询优化
    python运行内存分析
    【转】【WPF】WPF强制刷新界面
    【转】【WPF】Grid显示边框线
    流媒体服务新手入门教程03--音视频基础
    流媒体服务新手入门教程02--m7s环境搭建
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7244727.html
Copyright © 2011-2022 走看看