HDU5748---(记录每个元素的 最长上升子序列 nlogn)

分析:

给一个序列,求出每个位置结尾的最长上升子序列

O(n^2) 超时

#include "cstdio"
#include "algorithm"
#define N 1005
#define INF 0X3f3f3f3f
using namespace std;
int a[N];
int dp[N];
void solve(int n)
{
    for(int i=0;i<n;i++)
    {
        dp[i]=1;
        for(int j=0;j<i;j++)///往前找寻美妙的回忆
        {
            if(a[j]<a[i])
            {
                dp[i]=std::max(dp[i],dp[j]+1);
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        if(i==0)
            printf("%d",dp[0]);
        else
            printf(" %d",dp[i]);
    }
    printf("
");
}

int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        solve(n);
    }
}

优化为O(nlogn)  AC

#include "cstdio"
#define N 100005
#include "algorithm"
using namespace std;
int n;
int a[N];
int dp[N];
int ans[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&a[0]);
        int top=1;///最长上升子序列长度
        dp[1]=a[0];///=最后一个元素
        ans[0]=top;///每个位置的 最长上升..长度
        
        for(int j=1;j<n;j++)///对每个元素
        {
            scanf("%d",&a[j]);
            if(a[j]>dp[top])///变长
            {
                top++;
                dp[top]=a[j];
                ans[j]=top;
            }
            else
            {
                int pos=lower_bound(dp,dp+top,a[j])-dp;///二分查找位置 替换元素
                dp[pos]=a[j];
                ans[j]=pos;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i==0)
                printf("%d",ans[i]);
            else
                printf(" %d",ans[i]);
        }
        printf("
");
    }
}

 若只要最长...,只输出ans[n-1]

可将上述解法当做一模板

#include <iostream>  
#include <stdio.h>  
#include <algorithm>  
#include <string.h>  
using namespace std;  
int dp[20];  
const int inf=0x7fffffff;  
int a[7]={2,1,3,4,8,5,9};  
const int maxn=500005;  
int main()  
{  
    fill(dp,dp+7,inf);  
    for(int i=0;i<7;i++)  
    {  
        *lower_bound(dp,dp+7,a[i])=a[i];  
    }  
    int len=lower_bound(dp,dp+7,inf)-dp;  
    for(int i=0;i<len;i++)  
        cout<<dp[i]<<endl;  
    return 0;  
}
View Code
原文地址:https://www.cnblogs.com/kimsimple/p/6661559.html