求组合数的O(n^2)和O(n)解法及模板
生活随笔
收集整理的這篇文章主要介紹了
求组合数的O(n^2)和O(n)解法及模板
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
概率論中的組合數應該比較熟悉吧,在數論中組合數也具有重大意義,下面介紹組合數的解法:
方法一O(n^2):
利用公式(n,m)=(n-1,m-1)+(n-1,m):
模板:
#include<cstdio> const int N = 2000 + 5; const int MOD = (int)1e9 + 7; int comb[N][N];//comb[n][m]就是C(n,m) void init(){for(int i = 0; i < N; i ++){comb[i][0] = comb[i][i] = 1;for(int j = 1; j < i; j ++){comb[i][j] = comb[i-1][j] + comb[i-1][j-1];comb[i][j] %= MOD;}} } int main(){init(); }?
方法二(O(n)):
因為大部分題都有求余,所以我們大可利用逆元的原理(沒求余的題目,其實你也可以把MOD自己開的大一點,這樣一樣可以用逆元做)。利用公式:
我們需要求階乘和逆元階乘。
模板:
const int MOD = (int)1e9 + 7; int F[N], Finv[N], inv[N];//F是階乘,Finv是逆元的階乘 void init(){inv[1] = 1;for(int i = 2; i < N; i ++){inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;}F[0] = Finv[0] = 1;for(int i = 1; i < N; i ++){F[i] = F[i-1] * 1ll * i % MOD;Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;} } int comb(int n, int m){//comb(n, m)就是C(n, m) if(m < 0 || m > n) return 0;return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD; } int main(){init(); }?
轉載于:https://www.cnblogs.com/FrankChen831X/p/10665895.html
總結
以上是生活随笔為你收集整理的求组合数的O(n^2)和O(n)解法及模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android自定义Dialog及与Ac
- 下一篇: POJ1358 Agri-Net