南昌理工學院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的不...