C 最長上公升子串行

2021-09-26 04:20:20 字數 2424 閱讀 7215

題目描述

現有數列a1,a2,a3……an。在其中找到嚴格遞增序列ai1,ai2,ai3,……aik(1 <= i1 < i2 < i3 < …… < ik <= n),請找出序列a的最長上公升子串行的長度,既k的最大值。

輸入格式

第一行:乙個整數n。

第二行:n個整數a1,a2,a3……an。

輸出格式

一行,最大的k。

輸入樣例

10510

89710

1312

2513

輸出樣例

6
提到dp,就一定就要去想:狀態、轉移方程、初值和答案了。

狀態:dp[i]指在1~i這i個數中,必須包含a[i]這個數的最長上公升子串行。

轉移方程:if(a[j] < a[i]) dp[i] = max(dp[i], dp[j] + 1)(1 <= j <= i - 1)

其實這個的意思就是:如果說在1~(i - 1)這(i - 1)個數中,a[j] < a[i],a[i]就可以接上a[j],形成乙個比dp[j]又多了1的遞增序列,因此每次判斷並取最大值就行了。

初值:dp[i] = 1(乙個數本身就是乙個遞增序列)。

答案:max

(ps:nr指序列長度的上限)

# include

# include

# include

# include

# include

using

namespace std;

# define for(i, a, b) for(int i = a; i <= b; i++)

# define _for(i, a, b) for(int i = a; i >= b; i--)

const

int nr =

100000

;int n, ans;

int a[nr +2]

, dp[nr +2]

;int

main()

printf

("%d\n"

, ans)

;return0;

}

二維動態規劃的時間複雜度為on^2,太多了,我們想去優化,可是我們發現直接在二維上改好像改不了,沒辦法,只好再想乙個新的方法了。

這次,我們開乙個新的陣列f,f[i]表示當上公升子串行長度為i時,此子串行最後乙個元素的最小值。我們會發現這個f陣列是隨著i值的增加,f[i]不斷增大的單調佇列。因為如果長度為i的上公升子串行最後一位都為f[i]了,那長度(i + 1)的最後一位至少也得是f[i] + 1了吧。

這樣我們從1到n乙個元素乙個元素的分析,當到了第i個元素時,我們在f陣列中找第乙個大於等於a[i]的f[k],這就代表長度為(k - 1)的上公升子串行最後一位的最少值是f陣列中最後乙個小於a[i]的數,所以就讓我們就可以把a[i]放到長度為(k - 1)的這個上公升子串行的後面,形成乙個新的長度為k的這個上公升子串行,接下來更新f[k]的值f[k] = min(f[k], a[i])可我們發現我們找f[k]時就說了f[k]是f陣列中第乙個大於等於a[i]的數,所以直接f[k] = a[i]就好了。

下圖僅供參考。

其中,在f陣列中找第乙個大於等於a[i]的f[k]時,可以用到二分查詢函式中的lower_bound函式。

如果你還沒有學過lower_bound可以到此**學習lower_bound函式的用法

這樣時間複雜度就從on^2降到了onlogn,大大減少了時間的消耗。

以下為**:

# include

# include

# include

# include

# include

using

namespace std;

# define for(i, a, b) for(int i = a; i <= b; i++)

# define _for(i, a, b) for(int i = a; i >= b; i--)

const

int nr =

100000

;int n, ans;

int a[nr +2]

;int f[nr +2]

;int

main()

printf

("%d\n"

, ans)

;return0;

}

剩下的這三種都與第一種十分相像:

ps:cmp函式的寫法:

bool

cmp(

int x,

int y)

最長上公升子串行 c

題目描述 輸入描述 輸入包含多組資料,每組資料第一行包含乙個正整數n 1 n 1000 緊接著第二行包含n個正整數m 1 n 10000 代表隊伍中每位隊員的身高。輸出描述 對應每一組資料,輸出最長遞增子串行的長度。解題思路 1 什麼是遞增子串行?例 有乙個序列 其中 等都是原序列的遞增子串行 注意...

最長上公升子串行

問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...

最長上公升子串行

最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用 演算法 n 2 和 nlogn 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7.an,求它的乙個子串行 設為s1...