HDU 5673 catalan數的應用

2021-07-11 10:28:00 字數 1712 閱讀 2089

分析:

記路徑長度為n

n,那麼機械人最多向右走\lfloor \frac \rfloor⌊​

2​​n

​​⌋步並向左走\lfloor \frac \rfloor⌊​

2​​n

​​⌋步。

ans(n) = \sum_^ \rfloor} c_n^ \ catalan(i)an

s(n)

=∑​i

=0​⌊

​2​​

n​​⌋

​​c​

n​2i

​​ca

tala

n(i)

其中catalan(n)ca

tala

n(n)

表示第n

n個卡特蘭數。

卡特蘭數定義:catalan(n)=\frac^n}ca

tala

n(n)

=​n+

1​​c

​2n​

n​​​

​遞推公式catalan(n)=\frac\ catalan(n-1)ca

tala

n(n)

=​n+

1​​4

n−2​

​cat

alan

(n−1

) 基於nn

的取值範圍,此題可以預處理出1,000,0011,

000,

001以內的乘法逆元、卡特蘭數。

每次詢問,都可以遞推組合數,或者提前一次性預處理好階乘和階乘的逆元得到組合數;累加組合數與相應卡特蘭數的乘積,得到答案。

事實上,ans(n)an

s(n)

是第nn

個默慈金數,還有更高效的遞推公式:

m_=m_n+ \sum_^m_i m = \frac}m​

n+1​

​=m​

n​​+

∑​i=

0​n−

1​​m

​i​​

mn−1

−i=​

n+3​

​(2n

+3)m

​n​​

+3nm

​n−1

​​​​

。需要注意的是:

cc[ n] 位 n ! 的 對(1e9 + 7)的逆元,能預處理的都預處理成陣列,要不然使用多次會超時。

求逆元o(1)的方法

#include #include #include #include using namespace std;

typedef long long ll;

typedef long long ll;

#define rep(i,n) for(int i=0;i<(int)n;i++)

#define rep1(i,x,y) for(int i =(int)x;i<=(int)y;i++)

const int mod = 1e9 + 7;

const int n = 1e6 + 100;

int inv[n];

int inv(int x)

ll cat[n] , d[n], f[n] ,cc[n];

void init()

for(int i = 3 ; i= mod)

ans %= mod;

}printf("%d\n",(int)ans);

}return 0;

}

catalan數的應用 變形 HDU1133

檢視維基百科,對卡特蘭數公式證明是這樣的 令1表示進棧,0表示出棧,則可轉化為求乙個2n位 含n個1 n個0的二進位制數,滿足從左往右掃瞄到任意一位時,經過的0數不多於1數。顯然含n個1 n個0的2n位二進位制數共有 考慮乙個含n個1 n個0的2n位二進位制數,掃瞄到第2m 1位上時有m 1個0和m...

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...