POJ 3903 Stock Exchange 最长上升子序列

利用了二分的思想来找已经放进去的第一个比读入元素大的位置,然后替换一下就行,如果读入的数比头上的数目还大,那么更新头部,加入一个新的数,最后这个数组的大小就是最长的上升子序列了,复杂度大约nlogn,比传统的n2快了不少;

/*
ID: sdj22251
PROG: calfflac
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAX 100000000
#define LOCA
#define PI acos(-1.0)
using namespace std;
int a[100001]; //记录数组
int main()
{
#ifdef LOCAL
    freopen("ride.in","r",stdin);
    freopen("ride.out","w",stdout);
#endif
    int n, m, cnt, high, low, mid, i;
    while(scanf("%d", &n) != EOF)
    {
        cnt = 0; //最长序列个数
        for(i = 1; i <= n; i++)
        {
            scanf("%d", &m);
            if(cnt == 0 || m > a[cnt]) //如果是第一个或者比队头的大,则存入数组
            a[++cnt] = m;
            else
            {
                high = cnt;
                low = 1;
                while(low <= high) //在已存序列中寻找位置,将输入的数替换进去,这样可以保证一直是上升序列
                {
                    mid = (low + high) / 2;
                    if(a[mid] < m)
                    low = mid + 1;
                    else high = mid - 1;
                }
                a[low] = m;
            }
        }
        printf("%d\n", cnt);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值