Catalan数
卡特蘭數(shù)用于解決一些特定的排列問(wèn)題,一般是求解有多少種排列。
Catalan數(shù)的定義:
(1)當(dāng)n=1時(shí),C(1)=1。
(2)當(dāng)n>1時(shí),C(n) = C(1)*C(n-1) + C(2)*C(n-2) + ... + C(n-1)*C(1)
(3)當(dāng)然,還能這樣算:
(4)更厲害的,是可以這樣算,但可能不精確: (ps:這些都是經(jīng)過(guò)證明的公式)
注:所有的奇卡塔蘭數(shù)(即n為奇數(shù))Cn都滿足。
一般來(lái)說(shuō),求卡特蘭數(shù)有個(gè)基本問(wèn)題,而其他問(wèn)題一般可以轉(zhuǎn)成這個(gè)問(wèn)題。這個(gè)基本問(wèn)題是這樣的:一個(gè)n個(gè)bit的二進(jìn)制數(shù),如果其任意前綴都是1的個(gè)數(shù)>=0的個(gè)數(shù),求這樣的二進(jìn)制有多少個(gè)?可以根據(jù)catellan數(shù)的性質(zhì)直接求Cn即可。
經(jīng)典題(1):有n對(duì)括號(hào),請(qǐng)問(wèn)n對(duì)括號(hào)能組成多少個(gè)合法序列?比如"(())"就是合法。
思路:考慮前i個(gè)pre[i],可以這樣認(rèn)為,其中的左括號(hào)為1,右括號(hào)為0,那么就成功轉(zhuǎn)成了卡特蘭數(shù)的一般問(wèn)題了。這里有個(gè)問(wèn)題,編程之美中提到,f(2*n)=[1/(n+1)]*C(2*n,m),其實(shí)右式完全等于求Cn,也可以直接按Cn來(lái)求。但是為什么書(shū)里這么寫(xiě)呢?因?yàn)闀?shū)中考慮的是枚舉k為每個(gè)可能與首個(gè)左括號(hào)匹配的右括號(hào)的位置,假如規(guī)定括號(hào)序列的下標(biāo)是從0開(kāi)始的,由于k必須是奇數(shù)位置才合法,所以列出來(lái)的公式為 f(2n)=f(0)*f(2n-2)+f(2)*f(2n-4)+...f(2n-4)*f(2)+f(2n-2)*f(0),觀察到式子中沒(méi)有出現(xiàn)求奇數(shù)的f,因此直接將0~2n-1中的偶數(shù)映射過(guò)來(lái)就是1~n啦。
經(jīng)典題(2):12個(gè)高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對(duì)應(yīng)列的第一排的人高,問(wèn)排列方式有多少種?
思路:先將12個(gè)人升序排序,下標(biāo)分別為1~n。同樣,用0代表首行,用1代表第二行。那么每個(gè)后綴back[i]中1的個(gè)數(shù)就必須大于等于0的個(gè)數(shù)了,否則肯定存在一個(gè)j>=i,首行[j]>次行[j],即第一行有個(gè)人比第二行高了,不合法。答案也是求Cn。
經(jīng)典題(3):將一個(gè)具有n個(gè)頂點(diǎn)的凸多邊形切成多個(gè)三角形的方法有多少種?注意只能某一頂點(diǎn)切往另一頂點(diǎn)。
思路:凸多邊形的每條邊必須對(duì)應(yīng)一個(gè)三角形,那么現(xiàn)在的問(wèn)題只是求這條邊對(duì)應(yīng)的另一個(gè)頂點(diǎn)在哪里。同樣,這個(gè)頂點(diǎn)的位置也是枚舉,那么就將問(wèn)題分成了兩個(gè)小問(wèn)題,其實(shí)就是區(qū)間DP題。答案依然是Cn。
經(jīng)典題(4):有3個(gè)人要借書(shū),3個(gè)人要還書(shū)。要使得3個(gè)人都能借到書(shū),那么這6人進(jìn)館的序列有多少種?
思路:將還書(shū)的人看成0,借書(shū)的人看成1。只能在有人還了之后才能有人借得到。那么每個(gè)前綴pre[i]中1的個(gè)數(shù)必須>=0的個(gè)數(shù),又轉(zhuǎn)成了一般問(wèn)題。
同樣的問(wèn)題還有:”合法的入棧出棧序列有多少種?“和”合法的找錢(qián)給錢(qián)序列有多少種“等等。
經(jīng)典題(5):將一個(gè)具有n個(gè)頂點(diǎn)的凸多邊形切成多個(gè)三角形的方法有多少種?注意只能某一頂點(diǎn)切往另一頂點(diǎn)。
思路:凸多邊形的每條邊必須對(duì)應(yīng)一個(gè)三角形,那么現(xiàn)在的問(wèn)題只是求這條邊對(duì)應(yīng)的另一個(gè)頂點(diǎn)在哪里。同樣,這個(gè)頂點(diǎn)的位置也是枚舉,那么就將問(wèn)題分成了兩個(gè)小問(wèn)題,其實(shí)就是區(qū)間DP題。答案依然是Cn。
經(jīng)典題(6):一個(gè)n*n的網(wǎng)格,要從左下角的格子走到右上角的格子,在不踏入對(duì)角線的情況下,且第一步必須往右走,有多少種方案到達(dá)終點(diǎn)?
思路:要不碰到對(duì)角線,那么往右走的次數(shù)要時(shí)刻多于等于往上走的次數(shù)。又是可以轉(zhuǎn)成一般問(wèn)題。
經(jīng)典題(7):一個(gè)由n個(gè)節(jié)點(diǎn)組成的二叉樹(shù),不同構(gòu)的有多少棵?
思路: 考慮第n個(gè)點(diǎn)為根,那么左邊可能有0~n-1個(gè)點(diǎn),右邊就是剩下的點(diǎn),枚舉左邊有多少個(gè)點(diǎn)即可。求Cn。
經(jīng)典題(8):矩陣連乘問(wèn)題,n個(gè)矩陣相乘,要求為他們加括號(hào)改變乘法的順序,有多少種方法?
思路: 仍然是”合法的括號(hào)序列“的那道題。
總結(jié):通過(guò)上面的題觀察到,一共有兩種類型,一種是”括號(hào)匹配“類型,一種是”基本問(wèn)題“。如果需要匹配的,一般就是第一種類型,否則就是第二種。它們對(duì)應(yīng)的模型都差不多。
總結(jié)
- 上一篇: Ollydbg/x32dbg/x64db
- 下一篇: 选择中文英语疑问句