• noip模拟赛 序


    【问题背景】
    zhx 给他的妹子们排序。
    【问题描述】
    zhx N 个妹子, 他对第 i 个妹子的好感度为 ai,且所有 ai两两不相等。 现
    N 个妹子随意站成一排, 他要将她们根据好感度从小到大排序。 他使用的是
    冒泡排序算法(详见下)。如果排序过程中好感度为 ai的妹子和aj的妹子发生了交换, 那么她们之间会发生一场口角。
    现在 zhx 想知道, 给定妹子的初始排列, 在排序完成后, 最多存在多少个妹
    子, 她们任意两人之间没发生过口角。

    【输入格式】 

    第一行两个整数 N, 表示妹子数量。
    接下来一行 N 个整数 ai,表示初始第i个妹子的好感度.
    【输出格式】
    一行一个整数, 表示最多满足要求的妹子的个数。
    【样例输入】
    3
    3 1 2
    【样例输出】
    2
    【样例解释】
    {1, 2}
    对于100%的数据, 1 ≤   N ≤ 100000,0≤ai<N.
    分析:要找到这个集合,首先要搞清楚这个集合中的元素满足什么性质.冒泡排序和逆序对是相关的,每一对逆序对的两个数都会被交换一次.那么最后的集合中两两肯定都是顺序对,即i<j,a[i]<a[j],现在要求最大的集合,这就是LIS.数据比较大,要用O(NlogN)的解法.

    #include <map>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n, a[100010], s[100010], cur;
    
    int erfen(int x)
    {
        int l = 1, r = cur, ans = 1;
        while (l <= r)
        {
            int mid = (l + r) >> 1;
            if (s[mid] > x)
            {
                r = mid - 1;
                ans = mid;
            }
            else
                l = mid + 1;
        }
        return ans;
    }
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        s[0] = -1;
        for (int i = 1; i <= n; i++)
        {
            if (a[i] > s[cur])
                s[++cur] = a[i];
            else
            {
                int p = erfen(a[i]);
                s[p] = a[i];
            }
        }
        printf("%d
    ", cur);
    
        return 0;
    }
  • 相关阅读:
    ida动态调试--反反调试
    python读取配置文件
    问题解决:局域网内,为啥别人ping不到我的IP
    完全卸载MySQL
    JDK环境配置
    win10无法运行Vmware,怎么办
    查看ie版本
    公开的免费WebService接口分享,用于做接口练习
    SVN更改地址
    Loadrunner录制步骤及说明
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7736758.html
Copyright © 2020-2023  润新知