您的位置:首页 > 其它

最长上升(下降)子序列 O(nlogn)

2015-02-03 13:52 274 查看
http://www.rqnoj.cn/problem/156

题目描述

镇里举办贪吃比赛,一共比赛N天,规定:每次吃的必须比上次多,一天只能吃一次(撑死...),吃的天数最多的人将获得胜利,获得10000000000 mod 10 的奖金^_^

现在,Sally要参加比赛,她邀请参加OI的你一起帮忙,胜利后七三分成^_^

输入格式

第一行一个数N,表示吃的天数(N<=10000)

第二行N个数,表示每天能吃的数量(数量最多10000)

输出格式

一个数,表示最多吃的天数

输入:

6

1 2 3 1 5 6

输出

5

一开始的最长上升或者下降子序列两个for 暴力,现在改成二分了,也是暴力,省点时间!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
using namespace std;
int n;
int num[10001],a[10001],d[10001];
int main()
{
    cin.sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    num[1]=1;
    int mx=1;
    d[1]=a[1];
    for(int i=2;i<=n;i++)
    {
        int left=1;
        int right=mx;
        int temp=0;
        while(left<=right)
        {
            int mid=(right+left)/2;
            if(d[mid]<a[i])
            {
                left=mid+1;
                temp=mid;
            }
            else
                right=mid-1;
        }
        num[i]=temp+1;
        if(num[i]>mx)
            mx=num[i];
        d[num[i]]=a[i];
    }
    cout<<mx<<endl;
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: