• acd


    意甲冠军:一个人有两个属性S, B(1 ≤ Si, Bi ≤ 10^9),当两个人满足这两个属性 S1 < S2 && B1 < B2 要么 S1 > S2 && B1 > B2 时间,这两个男人不讨厌对方。现在给 N 个人(2 ≤ N ≤ 100 000)的属性,求最多能有多少个人,他们之间随意两人都不会讨厌对方。

    题目链接:http://acdream.info/problem?pid=1216

    ——>>easy想到是一个二维的LIS模型。。

          二维降一维,控制当中一维递增,对还有一维求LIS。

    (主要是在排序的时候。让第一维从小到大排,第二维从大到小排,那么,排序后对第二维求LIS的结果肯定不会出现当中的元素相应的第一维是同样的,由于同样的第一维相应的第二维是递减的,而对第二维求LIS是严格递增的。

    。)

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using std::sort;
    using std::lower_bound;
    
    const int MAXN = 100000 + 10;
    const int INF = 0x3f3f3f3f;
    
    struct PERSON
    {
        int id;
        int S;
        int B;
    
        bool operator < (const PERSON& e) const
        {
            return S < e.S || (S == e.S && B > e.B);
        }
    } person[MAXN];
    
    int N;
    int buf[MAXN];
    int lis[MAXN], who[MAXN], fa[MAXN], cnt;
    
    int LIS()
    {
        int ret = 1;
    
        memset(lis, 0x3f, sizeof(lis));
        memset(fa, -1, sizeof(fa));
        who[0] = -1;
        for (int i = 1; i <= N; ++i)
        {
            int id = lower_bound(lis + 1, lis + 1 + N, buf[i]) - lis;
            lis[id] = buf[i];
            who[id] = i;
            fa[i] = who[id - 1];
            if (id > ret)
            {
                ret = id;
            }
        }
    
        return ret;
    }
    
    void Read()
    {
        for (int i = 1; i <= N; ++i)
        {
            scanf("%d%d", &person[i].S, &person[i].B);
            person[i].id = i;
        }
    }
    
    void Init()
    {
        sort(person + 1, person + 1 + N);
        for (int i = 1; i <= N; ++i)
        {
            buf[i] = person[i].B;
        }
    }
    
    void Output(int x)
    {
        if (fa[x] == -1)
        {
            printf("%d", person[x].id);
            return;
        }
        Output(fa[x]);
        printf(" %d", person[x].id);
    }
    
    void Solve()
    {
        cnt = LIS();
        printf("%d
    ", cnt);
        Output(who[cnt]);
        puts("");
    }
    
    int main()
    {
        while (scanf("%d", &N) == 1)
        {
            Read();
            Init();
            Solve();
        }
    
        return 0;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    制作一个html中闪动的title 来提示消息
    Unicode与 utf8的互相转换
    程序员找女友的类
    使用php将数组转为XML
    自己动手画一个HTML5的按钮
    浏览器推通知给桌面
    如何使用定时任务
    封装之property,多态,鸭子类型,classmethod与staticmethod
    面向对象
    继承与派生
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4615861.html
Copyright © 2020-2023  润新知