算法学习之组合数学入门基础

组合数学基础知识,整理所学。

    一.  组合数递推公式:
        ��_��^��=��_(��−1)^(��−1)+��_(��−1)^��  
        C(n,m) = C(n-1,m)+C(n-1,m-1);

    二.   鸽笼原理
        描述:如果n个物体被放进m个盒子,那么至少有一个盒子有⌈��/��⌉个物体。 -->意思为向上取整,用floor函数可以实现
        经典案例: 
            对数列a1,a2,a3,……an,至少存在1≤i即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

你可能感兴趣的:(算法学习)