演算法學習之組合數學入門基礎
阿新 • • 發佈:2019-01-28
組合數學基礎知識,整理所學。
一. 組合數遞推公式: ��_��^��=��_(��−1)^(��−1)+��_(��−1)^�� C(n,m) = C(n-1,m)+C(n-1,m-1); 二. 鴿籠原理 描述:如果n個物體被放進m個盒子,那麼至少有一個盒子有⌈��/��⌉個物體。 -->意思為向上取整,用floor函式可以實現 經典案例: 對數列a1,a2,a3,……an,至少存在1≤i<j≤n,使得∑1_(��=��)^�� ��_�� 能被n整除。 -->即ai+..+aj 能被n整除。 證明如下: 作和函式 S1 = a1;S2 = a1+a2... ;Sn = a1+a2+a3+..+an; 假設這n個數不能被n整除,則餘數的域為1--n-1, 這就相當於把n-1個數放進n個籠子,肯定有兩個餘數相等,則肯定有Sj - Si 能被n整除。 三. 容斥原理 幾個集合並集的大小=所有單個集合的大小之和-(所有任意)兩個的交+(所有任意)三個的交-(所有任意)四個的交…… 比如��∪��∪�� = ��+��+��−��∩��−��∩��−��∩��+��∩��∩�� 四. 母函式 --生成函式 在數學中,某個序列的母函式(Generating function,又稱生成函式)是一種形式冪級數 其每一項的係數可以提供關於這個序列的資訊。使用母函式解決問題的方法稱為母函式方法。 普通型母函式 舉個例子: 若有1克、2克、3克、4克的砝碼各一枚,能稱出哪幾種重量?各有幾種可能方案? 現在x的指數表示稱出的重量。 1個1克的砝碼可以用函式1+1*x^1表示, 1個2克的砝碼可以用函式1+1*x^2表示, //如果有3個2g的砝碼呢? 表示為 1+x^2+x^4+x^6 1個3克的砝碼可以用函式1+1*x^3表示, 1個4克的砝碼可以用函式1+1*x^4表示, 我們拿1+x^2來說,前面已經說過,x表示砝碼,x的指數表示砝碼的重量!初始狀態時,這裡就是一個質量為2的砝碼。 那麼前面的1表示什麼?按照上面的理解,1其實應該寫為:1*x^0,即1代表重量為2的砝碼數量為0個。 所以這裡1+1*x^2 = 1*x^0 + 1*x^2,即表示2克的砝碼有兩種狀態,不取或取,不取則為1*x^0,取則為1*x^2 接下來我們把他們乘起來(1+��)*(1+��^2)*(1+��^3)*(1+��^4=1+��+��^2+〖2��〗^3+2��^4+2��^5+2��^6+2��^7+��^8+��^9+��^10 指數即拿的重量,係數就是對應的方案數(zhen tm niu bai) 五. 母函式模板: 存多項式。使用陣列維護的。下標是多項式的指數,存的是該項的係數! 存多項式。使用陣列維護的。下標是多項式的指數,存的是該項的係數!
//注意所有操作是從下標為0開始的! a[0]就是 1的係數,也就是常數項
#include
using namespace std;
int a[1000],b[1000];//a存多項式,下標是指數,存的是係數! b是中間的,存每一次的結果!
int v[100],num[100]; //硬幣面值,個數
int n; //n是硬幣種類數
void GFunction(){
for(int i= 0;i<=num[0]*v[0];i++) a[i] = 1; //初始化,
int lastindex = num[0]*v[0]; //記錄目前最大的多項式指數
for(int i = 1;i