1. 程式人生 > >最長上升子序列

最長上升子序列

ast ref open order 返回 就會 ati int nod

poj:Longest Ordered Subsequence 是一道簡單的最長上升子序列問題 用下面的dp代碼就可以輕松解決。 技術分享圖片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 
 7 int dp[1005],num[1005];
 8 
 9 int main()
10 {
11     int n,ans;
12     scanf("%d",&n);
13     ans=0;
14     for(int
i=0;i<n;i++) 15 { 16 scanf("%d",&num[i]); 17 dp[i]=1; 18 for(int j=0;j<i;j++) 19 { 20 if(num[i]>num[j]) 21 dp[i]= dp[i] > dp[j]+1 ? dp[i] :dp[j]+1; 22 } 23 ans=dp[i] >ans ? dp[i] :ans; 24 } 25 printf("
%d\n",ans); 26 return 0; 27 }
View Code 相同類型的問題 https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1134 這個連接上的最長遞增子序列問題用上面的代碼就會TLE 因為這個題目的數據不小,沒有優化的dp就很容易T掉 下面給出優化後的代碼
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#define inf 0x3f3f3f3f
#define Max 1000500
using namespace std;
int dp[Max],a[Max];

void solve(int n)
{
    for(int i=0;i<n;i++)
    {
        dp[i]=inf;
    }
    for(int i=0;i<n;i++)
    {
        *lower_bound(dp,dp+n,a[i])=a[i];///返回一個指針
    }

    printf("%d\n",lower_bound(dp,dp+n,inf)-dp);
}

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

最長上升子序列