Codeblock的快捷鍵說明:
1、按住Ctrl滾滾輪,代碼的字體會隨你心意變大變小
2、 在編輯區按住右鍵可拖動代碼
3、Ctrl+D可複製當前行或選中塊
4、Ctrl+Shift+C註釋掉當前行或選中塊,Ctrl+Shift+X則解除註釋。
5、Tab縮進當前行或選中塊,Shift+Tab減少縮進
6、需要更大編輯空間時,F2和Shift+F2分別可以顯隱下方Logs & others欄和左方的Management欄
7、Ctrl+PageUp 到達上一個函數,Ctrl+PageDown 到達下一個函數。 • Ctrl+B 添加書籤
void *memset(void *s,int ch,size_t n);
函數解釋:將 s 中前 n 個字節用 ch 替換並返回 s 。
頭文件:#include
//卡特蘭數:
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
h(n ) = h(n-1)*(4*n-2) / (n+1)
卡特蘭數:規定h(0)=1,而h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,h(6)=132,h(7)=429,h(8)=1430,h(9)=4862,h(10)=16796,h(11)=58786,h(12)=208012,h(13)=742900,h(14)=2674440,h(15)=9694845···
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, …
應用:
1、括號化
矩陣鏈乘: P=a1×a2×a3×……×an,依據乘法結合律,不改變其順序,只用括號表示成對的乘積,試問有幾種括號化的方案?(h(n-1)種)
f(n) = f(1)*f(n-1) + f(2)*f(n-2) + f(3)*f(n-3) + f(n-1)*f(1)
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
f(n) = h(n-1) ( n>=3 )(因爲h(n)中,n>=2 )
2、出棧次序
一個棧(無窮大)的進棧序列爲1,2,3,…,n,有多少個不同的出棧序列?
分析:對於每一個數來說,必須進棧一次、出棧一次。我們把進棧設爲狀態‘1’,出棧設爲狀態‘0’。n個數的所有狀態對應n個1和n個0組成的2n位二進制數。由於等待入棧的操作數按照1‥n的順序排列、入棧的操作數b大於等於出棧的操作數a(a≤b),因此輸出序列的總數目=由左而右掃描由n個1和n個0組成的2n位二進制數,1的累計數不小於0的累計數的方案種數。
n個數的進棧次序和出棧次序構成了一個含2n個數字的序列。第0個數字肯定是進棧的數,這個數相應的出棧的數一定是第2i+1個數。因爲如果是2i,那麼中間包含了奇數個數,這奇數個肯定無法構成進棧出棧序列。
設問題的解爲f(2n), 那麼
f(2n) = f(0)*f(2n-2) + f(2)*f(2n-4) + f(2n-2)*f(0)
f(2n) = h(n)。
類似問題:
n對括號有多少種匹配方式?( h(n) )
3、凸多邊形三角劃分
在一個凸多邊形中,通過若干條互不相交的對角線,把這個多邊形劃分成了若干個三角形。現在的任務是鍵盤上輸入凸多邊形的邊數n,求不同劃分的方案數f(n)。比如當n=6時,f(6)=14
分析:因爲凸多邊形的任意一條邊必定屬於某一個三角形,所以我們以某一條邊爲基準,以這條邊的兩個頂點爲起點P1和終點Pn(P即Point),將該凸多邊形的頂點依序標記爲P1、P2、……、Pn,再在該凸多邊形中找任意一個不屬於這兩個點的頂點Pk(2<=k<=n-1),來構成一個三角形,用這個三角形把一個凸多邊形劃分成兩個凸多邊形,其中一個凸多邊形,是由P1,P2,……,Pk構成的凸k邊形(頂點數即是邊數),另一個凸多邊形,是由Pk,Pk+1,……,Pn構成的凸n-k+1邊形。
此時,我們若把Pk視爲確定一點,那麼根據乘法原理,f(n)的問題就等價於——凸k多邊形的劃分方案數乘以凸n-k+1多邊形的劃分方案數,即選擇Pk這個頂點的f(n)=f(k)×f(n-k+1)。而k可以選2到n-1,所以再根據加法原理,將k取不同值的劃分方案相加,得到的總方案數爲:
f(n)=f(2)f(n-2+1)+f(3)f(n-3+1)+……+f(n-1)f(2)。
f(n)=h(n-2) (n=2,3,4,……)。
最後,令f(2)=1,f(3)=1。
思路:以凸多邊形的一邊爲基,設這條邊的2個頂點爲A和B。從剩餘頂點中選1個,可以將凸多邊形分成三個部分,中間是一個三角形,左右兩邊分別是兩個凸多邊形,然後求解左右兩個凸多邊形。
設問題的解f(n),其中n表示頂點數,設f(2) = 1,那麼f(3) = 1, f(4) = 2, f(5) = 5。f(2)*f(n-1)表示三個相鄰的頂點構成一個三角形,那麼另外兩個部分的頂點數分別爲2和n-1。那麼
f(n) = f(2)*f(n-1) + f(3)*f(n-2) + ......f(n-2)*f(3) + f(n-1)*f(2)。
f(n) = h(n-2)。
類似問題:
在圓上選擇2n個點,將這些點成對連接起來使得所得到的n條線段不相交的方法數?
思路:以其中一個點爲基點,編號爲0,然後按順時針方向將其他點依次編號。那麼與編號爲0相連點的編號一定是奇數,否則,這兩個編號間含有奇數個點,勢必會有個點被孤立,即在一條線段的兩側分別有一個孤立點,從而導致兩線段相交。設選中的基點爲A,與它連接的點爲B,那麼A和B將所有點分成兩個部分,一部分位於A、B的左邊,另一部分位於A、B的右邊。然後分別對這兩部分求解即可。
設問題的解f(n),那麼
f(n) = f(0)*f(n-2) + f(2)*f(n-4) + f(4)*f(n-6) + ......f(n-4)*f(2) + f(n-2)*f(0)。
f(0)*f(n-2)表示編號0的點與編號1的點相連,此時位於它們右邊的點的個數爲0,而位於它們左邊的點爲2n-2。依次類推。
f(0) = 1, f(2) = 1, f(4) = 2。結合遞歸式,不難發現
f(2n) =h(n)。
Cn = n*n 的方格地圖中,從一個角到另外一個角,不跨越對角線的路徑數;
4、給定節點組成二叉樹
給定N個節點,能構成多少種不同的二叉樹?(能構成h(N)個)(這個公式的下標是從h(0)=1開始的)
思路:可以這樣考慮,根肯定會佔用一個結點,那麼剩餘的n-1個結點可以有如下的分配方式,T(0, n-1),T(1, n-2),...T(n-1, 0),設T(i, j)表示根的左子樹含i個結點,右子樹含j個結點。
設問題的解爲f(n),那麼
假設f(0) = 1,那麼f(1) = 1, f(2) = 2, f(3) = 5。
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + .......+ f(n-2)*f(1) + f(n-1)*f(0)。
f(n) = h(n).
實例:
1、描述:有2n個人排成一行進入劇場。入場費5元。其中只有n個人有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人買票,售票處就有5元的鈔票找零?
思路:可以將持5元買票視爲進棧,那麼持10元買票視爲5元的出棧。這個問題就轉化成了棧的出棧次序數。由應用2的分析直接得到結果,
f(2n) = h(n)*n!*n!。(後面的*n!*n!爲進出棧的排列)
2、擁有 n+1 個葉子節點的二叉樹的數量爲h(n)
編程實例:
// 使用公式計算:h(n ) = h(n-1)*(4*n-2) / (n+1)
#include
#include
using namespace std;
//h(n ) = h(n-1)*(4*n-2) / (n+1)
int catelan1(int n)
{
if(n==0) return 1;
else return catelan1(n-1)*(4*n-2)/(n+1);
}
//h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
int catelan2(int n)
{
int i,j,h[100];
memset(h, 0, sizeof(h));
h[0]=h[1]=1;
for(i=2; i<=n; i++)
for(j=0; j
h[i] += h[j]*h[i-1-j];
return h[n];
}
//h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
int Cn(int n)
{
int i,sum=1;
for(i=1; i<=n; i++)
sum*=i;
return sum;
}
int catelan3(int n)
{
return Cn(2*n)/Cn(n)/Cn(n)/(n+1);
}
int main()
{
for(int i=0; i<=10; i++)
cout<<"h("<<i<<"):"<<catelan1(i)<<endl;
}
運行結果:
h(0):1
h(1):1
h(2):2
h(3):5
h(4):14
h(5):42
h(6):132
h(7):429
h(8):1430
h(9):4862
h(10):16796
Process returned 0 (0x0) execution time : 0.234 s
Press any key to continue.
公式3有點問題。。。
還有一種分級排列法,沒怎麼看明白。。。