1. 程式人生 > >多邊形劃分-卡特蘭數

多邊形劃分-卡特蘭數

區域賽系列一多邊形劃分

時間限制:1000 ms  |  記憶體限制:65535 KB 難度:2
描述

Give you a convex(凸邊形), diagonal n-3 disjoint divided into n-2 triangles(直線), for different number of methods, such as n=5, there are 5 kinds of partition method, as shown in Figure

輸入
The first line of the input is a n (1<=n<=1000), expressed n data set. The next n lines each behavior an integer m (3<=m<=18), namely the convex edges.
輸出
For each give m,, output how many classification methods. example output: Case #a : b
樣例輸入
3
3
4
5
樣例輸出
Case #1 : 1
Case #2 : 2
Case #3 : 5

卡特蘭數:

卡塔蘭數組合數學中一個常出現在各種計數問題中出現的數列。由以比利時的數學家歐仁·查理·卡塔蘭 (18141894)命名。

卡塔蘭數的一般項公式為                       另類遞迴式:  h(n)=((4*n-2)/(n+1))*h(n-1);

前幾項為 (OEIS中的數列A000108

): 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...

令h(0)=1,h(1)=1,catalan數滿足遞迴式:
  h(n)= h(0)*h(n-1) + h(1)*h(n-2) +  + h(n-1)h(0) (其中n>=2)

 另類遞迴式:  h(n)=((4*n-2)/(n+1))*h(n-1);

最典型的四類應用:(實質上卻都一樣,無非是遞迴等式的應用,就看你能不能分解問題寫出遞迴式了)
1.括號化問題。

  矩陣鏈乘: P=a1×a2×a3×……×an,依據乘法結合律,不改變其順序,只用括號表示成對的乘積,試問有幾種括號化的方案?(h(n)種)
2.出棧次序問題。

  一個棧(無窮大)的進棧序列為1,2,3,..n,有多少個不同的出棧序列?
  類似:
  (1)有2n個人排成一行進入劇場。入場費5元。其中只有n個人有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人買票,售票處就有5元的鈔票找零?(將持5元者到達視作將5元入棧,持10元者到達視作使棧中某5元出棧)
  (2)在圓上選擇2n個點,將這些點成對連線起來,使得所得到的n條線段不相交的方法數。
3.將多邊行劃分為三角形問題。

  將一個凸多邊形區域分成三角形區域的方法數?
  類似:一位大城市的律師在她住所以北n個街區和以東n個街區處工作。每天她走2n個街區去上班。如果她
  從不穿越(但可以碰到)從家到辦公室的對角線,那麼有多少條可能的道路?
  類似:在圓上選擇2n個點,將這些點成對連線起來使得所得到的n條線段不相交的方法數?
4.給頂節點組成二叉樹的問題。

  給定N個節點,能構成多少種形狀不同的二叉樹?
  (一定是二叉樹!
  先去一個點作為頂點,然後左邊依次可以取0至N-1個相對應的,右邊是N-1到0個,兩兩配對相乘,就是h(0)*h(n-1) + h(2)*h(n-2) + 
 + h(n-1)h(0)=h(n))
  (能構成h(N)個)

5,問題描述:
12個高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對應的第一排的人高,問排列方式有多少種?

我們先把這12個人從低到高排列,然後,選擇6個人排在第一排,那麼剩下的6個肯定是在第二排.
用0表示對應的人在第一排,用1表示對應的人在第二排,那麼含有6個0,6個1的序列,就對應一種方案.
比如000000111111就對應著
第一排:0 1 2 3 4 5
第二排:6 7 8 9 10 11
010101010101就對應著
第一排:0 2 4 6 8 10
第二排:1 3 5 7 9 11
問題轉換為,這樣的滿足條件的01序列有多少個。
觀察1的出現,我們考慮這一個出現能不能放在第二排,顯然,在這個1之前出現的那些0,1對應的人
要麼是在這個1左邊,要麼是在這個1前面。而肯定要有一個0的,在這個1前面,統計在這個1之前的0和1的個數。
也就是要求,0的個數大於1的個數。
OK,問題已經解決。
如果把0看成入棧操作,1看成出棧操作,就是說給定6個元素,合法的入棧出棧序列有多少個。
這就是catalan數,這裡只是用於棧,等價地描述還有,二叉樹的列舉、多邊形分成三角形的個數、圓括弧插入公式中的方法數,其通項是c(2n, n)/(n+1)。

程式碼:

#include<stdio.h>
long long num[25];
int main()
{
    int t,step=1;
    scanf("%d",&t);
    num[0]=1,num[1]=1,num[2]=2;
    for(int i=3;i<=18;i++)
    {
        long long sum=0,j=1;
        while(j<=i)
        {
            sum+=num[i-j]*num[j-1];
            j++;
        }
        num[i]=sum;
    }
//    for(int i=1;i<=8;i++)
//    {
//        printf("%lld\n",num[i]);
//    }
    while(t--)
    {
        int n;
        scanf("%d",&n);
        printf("Case #%d : %lld\n",step++,num[n-2]);
    }
    return 0;
}