c语言鸽笼原理,【算法】组合数学的整理

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

一.组合数递推公式:

𝐶_𝑛^𝑚=𝐶_(𝑛−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)

五.  母函数模板:

存多项式。使用数组维护的。下标是多项式的指数,存的是该项的系数!

1       //注意所有操作是从下标为0开始的! a[0]就是 1的系数,也就是常数项

2

3 #include

4

5 using namespacestd;6

7 int a[1000],b[1000];//a存多项式,下标是指数,存的是系数! b是中间的,存每一次的结果!

8

9 int v[100],num[100]; //硬币面值,个数

10

11 int n; //n是硬币种类数

12

13 voidGFunction(){14

15 for(int i= 0;i<=num[0]*v[0];i++) a[i] = 1; //初始化,

16

17 int lastindex = num[0]*v[0]; //记录目前最大的多项式指数

18

19 for(int i = 1;i

21 for(int j = 0;j<=lastindex;j++){22

23 for(int k = 0;k<=num[i]*v[i];k+=v[i]){24

25 b[j+k] +=a[j];26

27 }28

29 }30

31 lastindex += num[i]*v[i];32

33 for(int j = 0;j<=lastindex;j++){34

35 a[j] =b[j];36

37 b[j] = 0;38

39 }40

41 }42

43 return;44

45 }46

47

48    //测试

49

50 intmain(){51

52 v[0] = 1,v[1] = 2,v[2] =3,v[3] = 4;53

54 n =4;55

56 for(int i =0 ;i<4;i++){57

58 num[i] = 1;59

60 }61

62 GFunction();63

64 for(int i = 0;i<=10;i++){65

66 cout<

68 }69

70 }

令:指数型母函数:

解决多重集合的排列问题。

写母函数的时候,默认系数不是1,而是1/"对应幂次的阶乘 "

乘积对应系数分母保持不变,此时分子是排列数。

七.  错排数

十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?

通项公式:D(𝑖)=𝑖!*( 1/2!  −  1/3! +…+  (−1)^𝑖 *1/𝑖!)

近似公式:D(𝑖)=⌊𝑖!/𝑒+0.5⌋   此为i/e + 0.5 向下取整!

递推公式:D(𝑖)=(𝑖−1)*(𝐷(𝑖−1)+𝐷(𝑖−2))

应用:n个元素的排列都不在自己原有位置上的方案数;

八. 卡特兰数

通项公式:ℎ(𝑛)=C(2n,n) - C(2n,n-1)

递推公式:ℎ(𝑛)=h(𝑛−1) *(4𝑛−2)/(𝑛+1)

前几项为1, 1, 2, 5, 14, 42, 132……(从h(0)开始)

应用:n个结点能构成h(n)种不同的二叉树;

按1、2……n的次序进栈,有h(n)种不同出栈序列;

n对小括号进行有效匹配的方案数为h(n)……

九.  二项式定理深入理解

〖(𝑎+𝑏)〗^𝑛=𝑎^𝑛+𝐶_𝑛^1 𝑎^(𝑛−1) 𝑏+𝐶_𝑛^2 𝑎^(𝑛−2) 𝑏^2+…+𝐶_𝑛^(𝑛−2) 𝑎^2 𝑏^(𝑛−2)+𝐶_𝑛^(𝑛−1) 𝑎^1 𝑏^(𝑛−1)+𝑏^𝑛

理解:

有n项(a+b)相乘,我从这里面找a的n次方系数,就是n项都选a,这有一种法;

如果找 a的n-2*b的2 系数,就是n个式子选两个2,有C(n,2)种法。

算法持续更新,以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值