NOIP模拟赛-冒泡排序(Sort)

题目在这里

先看一眼数据范围,emm,发现10,000,0,显然不是暴力

然后我们看一下什么样的数字可能组成独立集-->显然是两个永远不会被交换的数字,那什么时候不会被交换呢?根据冒泡排序的原理,当a比b小,且a在b左侧时,他们不会交换,所以说,把能放到一起的数字单独拎出来,他们一定是单调不降的,但是题目中说a[i]互不相同,所以就保证了单调上升,那么我们只需要在原序列上跑一个最长上升子序列,最长上升子序列的长度,即为最大独立集的大小

代码(为了证明没有看std,我用了自己的板子233)

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=200500;
int a[M],nln[M];
int n,lon=1,lim;
inline int read()
{
    int x=0;char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
    return x;
}
inline int twomid(int emm)
{
    int l,r,mid;
    l=0,r=lon;
    while (l<r)
    {
        mid=(l+r)>>1;
        if (nln[mid]>=a[emm]) r=mid;
        else l=mid+1;
    }
    return l;
}//二分优化->O(nlogn)
int main()
{
    n=read();
    for (int i=1;i<=n;i++) a[i]=read();
    nln[1]=a[1];
    for (int i=2;i<=n;i++)
    {
        if (a[i]>nln[lon]) nln[++lon]=a[i];
        else lim=twomid(i),nln[lim]=a[i];
    }
    cout<<lon;
    return 0;
}//最长上升子序列求解大小

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80929323
今日推荐