組合數學 求組合數

2021-10-13 17:15:53 字數 2556 閱讀 6157

對於求組合數,要根據所給資料範圍來選擇合適的演算法

這道題中所給的資料範圍適合用打表的方法直接暴力求解

先用4e6的複雜度預處理出所有的情況,再用1e4的複雜度完成詢問即可

#include

using

namespace std;

const

int n =

2010

;const

int mod =

1e9+7;

int c[n]

[n];

void

init()

}}intmain()

return0;

}

對於這道題的資料範圍,直接給出二維陣列大表就不太合適了

我們需要在這裡預處理出所有的階乘和階乘的逆元

運用組合數公式求解

這裡處理逆元是因為我們需要把除法轉化為乘法(具體內容可以看之前寫過的)

#include

using

namespace std;

typedef

long

long ll;

const

int n =

1e5+

10, mod =

1e9+7;

int fact[n]

;//預處理出所有的階乘

int infact[n]

;//預處理出所有階乘的逆元

intquickmod

(int a,

int k,

int p)

return res;

}void

init()

}int

main()

return0;

}

這裡給定的資料範圍更大,引入乙個定理來解決

盧卡斯定理:

在這裡只需要運用這個定理即可

在數學知識中,除乙個數一定要注意使用乘逆元的形式,保證不會出現取捨問題

#include

using

namespace std;

typedef

long

long ll;

intquickmod

(int a,

int k,

int p)

return res;

}intc(

int a,

int b,

int p)

return res;

}int

lucas

(ll a, ll b,

int p)

intmain()

return0;

}

這裡可以利用組合數公式求解

如果要直接用高精度的話需要寫乙個乘法乙個除法比較麻煩

所以可以先進行因式分解,將答案分解成因式相乘的形式在利用高精度相乘進行解決

#include

using

namespace std;

const

int n =

5010

;int primes[n]

, cnt;

int sum[n]

;bool st[n]

;void

get_primes

(int n)}}

intget

(int n,

int p)

//分解質因數,求n這個數中有多少個p

return res;

}vector<

int>

mul(vector<

int> a,

int b)

while

(t)return c;

}int

main()

這個題用到了卡特蘭數

將這個題目中的01序列抽象在乙個座標系中,0表示向右,1表示向上

因此題目中的字首條件即表示所走的每一步都要在y=x這條直線的一側即可

這種做法即是用卡特蘭數來進行解決的

#include

using

namespace std;

typedef

long

long ll;

const

int mod =

1e9+7;

intquickmod

(int a,

int k,

int p)

return res;

}int

main()

吉首 組合數 求組合數因子個數

時間限制 1 sec 記憶體限制 128 mb 求組合數c n,m 以及c n,m 因子個數。n和m,其中0 m n 50,以eof結束。該組合數結果。3 2 4 23 2 6 4先利用楊輝三角求出組合數,然後就是求出因子數了 求因子數 素數分解的唯一性,乙個數可以被分解成若干素數相乘 p1 x1 ...

組合數學筆記

從n個數中選m個數,每個數至多選一次,方案數 性質 c n,0 c n,n 1 c n,m c n,n m c n,m c n 1,m 1 c n 1,m 楊輝三角 二項式展開 x y n i 0.n c n,i x iy n i 那這裡先說一下楊輝三角 前提 每行端點與結尾的數為1 每個數等於它上...

SPOJ INTSUB 組合數學

題目鏈結 題意 給你乙個集合,問有多少個子集是有趣的。有趣的集合定義是,集合中兩個不一樣的數,其中a是集合裡的最小值,b是a的倍數。題解 對於數字a,集合中存在x 2n a 1個大於a的倍數,也存在y 2n x a個大於a但不是a的倍數的數。對於有趣的集合必須要出席那大於a的倍數,一共有2 x 1種...