1. 程式人生 > 實用技巧 >51nod 2080 最長上升子序列

51nod 2080 最長上升子序列

題目網址:http://class.51nod.com/Challenge/Problem.html#problemId=2080

一、題目描述

一個數列的最長上升子列,是指其所有遞增的子列中最長的一個子列

給定一個長度為 n 的數列 an,求這個數列的最長上升子列的長度

例如對數列 1 7 2 8 3 4,這個數列的最長遞增子數列是 1 2 3 4,長度為 4;次長的長度為 3, 包括 1 7 8、1 2 3 等。

輸入描述

第一行一個正整數 n,表示數列元素個數,n<=1000

第二行 n 個正整數,從左到右給出數列的每一項

輸出描述

一行一個正整數,表示最長上升子數列的長度

樣例輸入

8
5 1 6 8 2 4 5 10

樣例輸出

5

二、解題思路

我們定義dp[i]為以a[i]為結尾的最長上升子序列的長度。

a[i]結尾的上升子序列得滿足:

1、j<i(以a[j]為結尾的上升子序列)

2、a[j]<a[i]

3、看哪個最大

①以a[j]結尾的上升子序列結尾加上1(a[i])後得到的子序列。

②a[i]自己成立一個子序列

把最大的賦值到數組裡存起來,最後看數組裡的最大值

時間複雜度是O(n2)。

三、AC程式碼

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using
namespace std; int main(){ int n, a[1005], sum[100005]={0}, ans=0; cin >> n; for(int i = 1;i <= n;i++){ cin >> a[i]; } for(int i = 1;i <= n;i++){ sum[i] = 1;//把每個數的長度初始值賦值為 1 for(int j = 1;j <= i-1;j++){//和a[i]前面所有的數作比較 if(a[j] < a[i]){//
如果後面的數大於前面的數 //說明可以考慮要不要把a[i]這個數也加入前面的序列 //看是前面的序列再加上1(a[i])長 //還是a[i]自己成立一個序列長 sum[i] = max(sum[i], sum[j]+1); //把更長的那個賦值到sum[i]裡面去 } } ans = max(ans,sum[i]);//找出題目要求的最長的序列 } cout << ans << endl; return 0; }