定義:從(0,0)到(n,n),不越過(可以接觸)直線y=x(即每一步的落腳點都滿足y>=x),且每次只能往上或往右走。求方案數。
結果:c(2n,n)-c(2n,n-1) (程式設計是可以實現小資料的)
n比較小時可以列舉,不過n可能會很大
證明方法:有很多種,自己上維基百科就能搜到(這裡給大家介紹一種不太常見的方法。
注意到答案為c(2n,n)/(n+1)
若不要求不越過y=x,答案為c(2n,n) (求法應該知道吧)
所以我們想到:定義p(l)為任意一條路徑l在y=x下方所行走的路徑的長度和。顯然2|p(l)
圖中p為4,(圖直接從維基百科上覆制的)
設滿足p(l)=k的路徑條數為f(k),則f(0)即為所求
我們證明:f(0)=f(2)=...=f(2n)
首先想到直接證。不過如果可以就求完了。
其次想到化歸。我們證明任意一條滿足p(l)=2k的路徑l都可以化歸為滿足p(l')=2k+2的l'(2k-2同理)
如圖,黑色箭頭為調整箭頭(將l劃分為若干個箭頭,第乙個向右且恰好碰到y=x的箭頭),記為b
剩下的部分,b前面的所有箭頭記為a(紅色部分),後面的記為c(綠色部分)
則路徑l可記為a->b->c
將l'定義為c->b->a即可(右圖)
於是我們將左圖化歸到了右圖
此時p(l')=p(l)+2
同理可從右圖化歸到左圖
得證這麼做有乙個好處:注意原分界線斜率k=1
若k=p或1/p,p為正整數
則種數為c((p+1)n,n)/(pn+1).(方法類似)
題目:hdu1023
主要就是高精度
上**:
#include
using
namespace
std;
int c[110][110];
int l[110];
void
cat()
while(mor)
//高精度乘法
mor=0;
for(int j=len-1;j>=0;j--)
while(!c[i][len-1])len--;
l[i]=len;
}}int n;
intmain
() //system("pause");
return0;}
/**/
注:此處運用了另一遞推式
h(n)=h(n-1)*(4*n-2)/(n+1)
Catalan數(卡特蘭數)
卡特蘭數 規定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 969484...
卡特蘭數 Catalan數
卡特蘭數 規定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 969484...
Catalan數(卡特蘭數)
2012 04 12 21 08 13 標籤 卡特蘭數 原始出處 作者資訊和本宣告。否則將追究法律責任。卡特蘭數 規定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 58...