子串行問題

2021-10-23 13:58:09 字數 3622 閱讀 9685

南昌理工學院ps:(這周划水嚴重,就不發學習總結了)

最長上公升子串行lis)

lis(最長上公升子串行)(本蒟蒻只會用) 想理解點這

n*n模板

//定義a[n]為要求的序列

for(

int i =

1; i <= n;

++i)

dp[i]

= na +1;

}

nlogn模板

用二分的方法進行查詢比較,節省時間

//查詢a[n],

int len =1;

memset

(d,127

,sizeof

(d))

; d[len]

= a[1]

;for

(int i =

2; i <= n;

++i)

d[l]

= a[i];}

} cout << len << endl;

lis(n *n)經典例題合唱隊形

解法:先正著求一遍lis再反求一遍lis,取最大值 - 1即可(因為最大值算了兩遍)。

舉例:輸入 8

186 186 150 200 160 130 197 220

正求lis 1 1 1 2 1 1 2 3

反求lis 2 2 1 3 2 1 1 1

max 3 3 2 5 3 2 3 4

ac**

#include

#include

using namespace std;

int n, ans =

0, na;

int dp[

101]

, f[

101]

;int a[

101]

;int

main()

for(

int i =

1; i <= n;

++i)

dp[i]

= na +1;

}for

(int i = n; i >0;

--i)

f[i]

= na +1;

}for

(int i =

1; i <= n;

++i)

cout << n - ans +

1<< endl;

return0;

}

lis(nlogn)例題 飛彈攔截

解法:第一問正著用lis(nlogn)求一遍最長下降子串行。

第二問正著用lis(nlogn)求一遍最長上公升子串行的長度(因為有乙個遞增的話,就要多一台。)不理解的可以手推或者去看看狄爾沃斯定理 (看了可能會… )。

ps:因為資料過大,用 n* n 的求lis只能過一半(100分),所以要用nlogn(200分)。

ac**

#include

#include

using namespace std;

int a[

1000001

], d[

100001];

int u, n =

0, ans =

0, len =1;

intmain()

memset

(d,127

,sizeof

(d))

; d[len]

= a[1]

;for

(int i =

2; i <= n;

++i)

d[l]

= a[i];}

} cout << len << endl;

len =1;

memset

(d,-1,

sizeof

(d))

; d[1]

= a[1]

;for

(int i =

2; i <= n;

++i)

d[l]

= a[i];}

} cout << len << endl;

return0;

}

解釋

n*n模板

#include

#include

#include

using namespace std;

const

int n =

1000

;char a[n]

,b[n]

;int dp[n]

[n];

intmain()

else}}

printf

("%d\n"

,dp[lena]

[lenb]);

}return0;

}

nlogn

轉化:將lcs問題轉化成lis問題。

假設有兩個序列 s1[ 1~6 ] = , s2[ 1~7 ] = 。

記錄s1中每個元素在s2**現的位置, 再將位置按降序排列, 則上面的例子可表示為:

loc( a)= , loc( b ) = , loc( c ) = , loc( d ) = 。

將s1中每個元素的位置按s1中元素的順序排列成乙個序列s3 = 。

在對s3求lis得到的值即為求lcs的答案。(出處

例題回文子串

思路:把得到的序列a倒序處理一下,得到乙個新序列b.

求一下a, b的最長公共子串行的長度n,輸出a序列長度 - n.

ac**

#include

#include

using namespace std;

string a, b;

int dp[

1001][

1001];

int len1, len2;

void

lcs(

int i,

int j)}}

intmain()

lcs(len1, len2)

; cout << len1 - dp[len1]

[len2]

;return0;

}

nlogn 例題模板題

ac**

#include

#include

using namespace std;

int a[

100001

], b[

100001

], map[

100001

], f[

100001];

int n, len =0;

intread()

while

(ch >=

'0'&& ch <=

'9')

return x * f;

}int

main()

f[l]

=min

(map[b[i]

], f[l]);

}}cout << len;

return0;

}

子串行問題

最近做了兩道子串行問題,分別是 53 最大子串行和和152 乘積最大子串行 他們解決的辦法大致相同,都是經過一次遍歷儲存乙個遍歷到當前數字的最大值,然後保留乙個當前增益或但當前成績,於是放到一起做乙個總結。53 最大子串行和 來自leetcode題解 動態規劃的是首先對陣列進行遍歷,當前最大連續子串...

子串行問題

1.最長上公升子串行 乙個數的序列bi,當b1比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等。這些子串行中最長的長度就是4,比如子串行 1,3,5,8 你的任務就是對於給定的序列,求出最長上公升子串行的長度。3.最大子段和問題 問題分析 狀態設計 d...

最長不降子串行問題

一 問題 輸入 設有由n個不相同的整數組成的數列,記為 a 1 a 2 a n 且a i a j i j 若存在i1長度為e的不下降序列。輸出 程式要求,當原數列給出之後,求出最長的不下降序列。例子 數列3,18,7,14,10,12,23,41,16,24。3,18,23,24就是乙個長度為4的不...