UVa:481 What Goes Up

LIS+打印最优解。O(n^2)会超时,所以用O(nlgn)的算法。

a[]表示原序列;dp[i]表示以dp[i]为尾元素的最长递增序列长度为i;dpos[i]表示a[i]在dp[]中的下标;pre[i]表示以a[i]为尾元素的最长递增序列中a[i]之前的元素下标。

最后递归打印pre[]即可。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 100000
#define INF 0x7f7f7f7f
using namespace std;
int a[MAXN];
int dp[MAXN];
int dpos[MAXN];
int pre[MAXN];
void Traversal(int val)
{
    if(val==0) return ;
    Traversal(pre[val]);
    printf("%d\n",a[val]);
}
int main()
{
    int N=1;
    while(scanf("%d",&a[N])!=EOF) N++;
    memset(dp,INF,sizeof(dp));
    dp[0]=-INF;
    int mx=0,ans=0;
    for(int i=1; i<N; ++i)
    {
        int p=lower_bound(dp,dp+N,a[i])-dp;
        dp[p]=a[i];
        dpos[p]=i;
        pre[i]=dpos[p-1];
        if(p>mx)
        {
            mx=p;
            ans=i;
        }
    }
    printf("%d\n",mx);
    printf("-\n");
    Traversal(ans);
    return 0;
}


 

你可能感兴趣的:(动态规划,LIS)