線性DP 最長不下降子串行 LIS

2021-07-15 14:01:59 字數 1401 閱讀 5767

題目:

例1 求最長不下降子串行。

由n個不相同的整數組成的數列,記為:a(1),a(2),…,a(n)且a(i)≠a(j)(i≠j),例如,3,18,7,14,10,12,23,41,16,24.若存在i1

<i2

3<…e且有a(i1)2)<…e),則稱其為長度為e的不下降子串行。如上例中3,18,23,24就是乙個長度為4的不下降子串行,同時也有3,7,10,12,16,24長度為6的不下降子串行。程式要求,當原數列給出之後,求出最長的不下降子串行的資料個數。

輸入檔案:

第一行為n(1≤n≤5000),第二行為n個整數,之間用空格隔開。

輸出檔案:

最長的不下降子串行的資料個數。

輸入樣例:

10

3 18 7 14 10 12 23 41 16 24

輸出樣例:

6

思路:

dp入門題,狀態轉移方程:f[i] = max + 1 (1 <= j < i);

狀態轉移方程f[i] = max+1 要求a[j] < a[i], 那a[j] > a[i]怎麼辦?

我一開始有這樣的疑問,其實是對 f[i] 有誤解:

f[i] 不代表到 i 位置為止的最長不下降子串行的個數

f[i] 代表以 a[i] 為結尾的最長不下降子串行的個數,基於以 a[i] 為結尾這個條件,自然 a[j] < [i],最後只需要遍歷一遍 f[i] 求其最大值就好

**:

#include #include #include #include using namespace std;

/*狀態轉移方程f[i] = max +1 (1 <= j < i);

f[i] 代表以 a[i] 結尾的最長不下降子串行

最後只需要遍歷一遍f[0~n-1]最大的是誰就好

*/int f[20];

int maxn;

int n;

void lis_dp(int *a)

}}int main()

/*10

3 18 7 14 10 12 23 41 16 24

*/

反思:關注 f[i] 或者 f[i][j] 等所代表的確切意思

DP 最長不下降子串行 LIS

同類的問題還有 最長上公升子串行 最長下降子串行 他們的不同就在於定義的core規則不同,有的是 有的是 有的是 由此啟發,我們可以在解決其他的問題,不一定是比較數的大小的問題裡面抽象出這種模型.下面介紹這種動態規劃入門都會介紹的問題的思路.首先我們從頭開始分析這個問題.對這個序列中的每乙個數的 有...

最長不下降子串行LIS

最長上公升子串行問題是解決很多問題的根本,它能幫助你理解二分的思想。考慮一下 對於乙個序列 n nn 請你查詢n nn中最長的子串行a aa,使得任意 i i j 時 a i a i a i a i a i a i 例如乙個長度為5 55的n nn 5553 331112 22444 顯然,它的最長...

LIS最長不下降子串行

在乙個序列中找到乙個最長的子串行 可以不連續 使得這個子串行不下降,即非遞減的。核心部分找到狀態轉移方程 dp i max j 1,2,i 1 a j 附上我的 include include includeusing namespace std const int maxn 10010 int d...