zoukankan      html  css  js  c++  java
  • 排列组合问题的一些整理

    初步:加法原理和乘法原理

    概念:

    加法原理是分类计数原理,常用于排列组合中,具体是指:做一件事情,完成它有n类方式,第一类方式有M1种方法,第二类方式有M2种方法,……,第n类方式有Mn种方法,那么完成这件事情共有M1+M2+……+Mn种方法。
    做一件事,完成它需要分成n个步骤,做第一 步有m1种不同的方法,做第二步有m2种不同的方法,……,做第n步有mn种不同的方法。那么完成这件事共有 N=m1×m2×m3×…×mn 种不同的方法。

    这个感觉大家都知道(小学奥数就开始学了吧qwq),感觉没有什么好说的qwq

    例题参照:AHOI2009 中国象棋

    这个题因为和DP结合,状态设计比较难想。但是当我们用(f[i][j][k])来表示到第i行,其中j列摆放了一个棋子,k列摆放了两个棋子之后,我们不难发现状态的转移就是其实就是加法原理和乘法原理的应用:
    以下是核心代码:

    dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k])%mod;
    //这一行什么都不放
    dp[i][j-1][k+1]=(dp[i][j-1][k+1]+j*dp[i-1][j][k])%mod;
    //这一行在原先只有一个棋子的那一列放一个棋子
    dp[i][j+1][k]=(dp[i][j+1][k]+(m-k-j)*dp[i-1][j][k])%mod;
    //这一行在原先没有棋子的那一列放一个棋子
    dp[i][j+2][k]=(dp[i][j+2][k]+(m-k-j)*(m-k-j-1)/2*dp[i-1][j][k])%mod;
    //这一行在原先没有棋子的两列分别摆放一个棋子
    dp[i][j][k+1]=(dp[i][j][k+1]+(m-k-j)*dp[i-1][j][k]*j)%mod;
    //这一行在原先有一个棋子和没有棋子的两列分别放一个
    dp[i][j-2][k+2]=(dp[i][j-2][k+2]+j*(j-1)/2*dp[i-1][j][k])%mod;
    //这一行在原先有一个棋子的两列分别摆放一个棋子
    

    加法原理和乘法原理的区别:

    一个与分类有关,一个与分步有关;加法原理是 “分类完成”,乘法原理是 “分步完成”。

    初识排列

    定义

    (n)个不同元素中,任取(m)(m<=n,m与n均为自然数, 下同)个元素按照一定的顺序排成一列,叫做从(n)个不同元素中取出(m)个元素的一个排列;从(n)个不同元素中取出(m)((m<=n))个元素的所有排列的个数,叫做从(n)个不同元素中取(m)个元素的排列数,用符号(A_n^m) 表示。

    计算公式

    (A_n^m=frac{n!}{(n-m)!})

    常见问题

    1、全排列问题
    (A_n^n=n(n-1)(n-2)...3 imes 2 imes 1=n!)

    2、部分排列
    就是上面的计算公式qwq

    初识组合

    定义:

    (n)个人中选(m)((m<=n)) 个出来,不排队,不在乎顺序就是(C_n^m)
    它和排列有关系为:(C_n^m imes A_m^m=C_n^m imes m!=A_m^n)
    (解释:因为要考虑顺序,选出来的那m个人还需要全排列)

    公式:

    1、(C_m^n=frac{m!}{n! imes (m-n)!})

    2、(C_m^n=C_m^{m-n})

    3、(C_m^n=C_{m-1}^n+C_{m-1}^{n-1})

    4、(C_m^{n+1}=frac{C_m^{n} imes (m-n)}{n+1})

    5、(C_{m}^{0}+C_{m}^{1}+C_{m}^{2}+...+C_{m}^{m}=2^{m})

    • 对于第二个公式应该很好理解,就是反选,方案数量自然是一样的。这体现的是它良好的对称性。

    • 第三个公式平常用来递推。可以划分为子问题理解:为如果选第n个数,那么就是在n-1个数里面选择m-1个数,如果不选第n个数,就是在n-1个数里面选m个数。证明如下:

    (∵C_{m}^{n}=frac{n!}{m!(n-m)!})

    (∵C_{m}^{n-1}=frac{(n-1)!}{m!(n-m-1)!})

    (∴C_{m}^{n-1}=frac{(n-1)!}{m!(n-m-1)!}=frac{(n-1)!(n-m)}{m!(n-m)!})

    (∵C_{m-1}^{n-1}=frac{(n-1)!}{(m-1)!(n-m)!}=frac{(n-1)!m}{m!(n-m)!})

    (∴C_{m-1}^{n-1}+C_{m-1}^{n})

    (=frac{(n-1)!m}{m!(n-m)!}+frac{(n-1)!(n-m)}{m!(n-m)!})

    (=frac{n!}{m!(n-m)!})

    (=C_m^n)

    • 第四个公式很好证明(展开即可),这里介绍它的应用:(二项式展开)求((a+b)^n)展开式的各项系数。
      我们会想到杨辉三角进行预处理,但是也可以直接利用公式:
      (C_n^{m+1}/C_n^m=frac{n-m}{m+1})递推来解决。

    有限的可重复元素的排列

    假设现在有n个元素,对于第一类元素(n_1),有sum1个重复,第二类元素(n_2),有sum2个重复......第m类元素(n_m),有summ个重复,总方案数为:

    [frac{n!}{sum_1! imes sum_2! imes ... imes sum_m!} ]

    附上一张来自wikipedia的图帮助理解:

    无限的可重复元素组合问题

    上面讲解的是有限的可重复元素排列问题,下面讲无限的可重复元素排列问题(就是每个元素都可以用无限多次参与排列)

    现在我们从m个元素中选择k个元素的,然后我们将这k个元素进行排序之后应该是这个样子:(设我们选择的数为编号为(a_i)

    (1<=a_1<=a_2<=......<=a_k<=m)

    那么现在我们将等于号消去:

    (1<=a_1<=a_2+1<=a_3+2<=......<=a_k+k-1<=m+k-1)

    现在我们设(b_i=a_i+i-1),那么很容易我们可以发现

    (1<=b_1<b_2<b_3<......<b_k<=n-k+1)

    那么现在问题就转换成了在([1,n+k-1])中选择k个不重复的元素了,那么根据我们的组合公式,自然是(C_{m+k-1}^k)了qwq

    同理还有求编号在1~n的元素中取k个元素,使得他们的编号不相邻。公式是一样的,证明也是一样的。

    二项式

    这里有一张来自wikipedia的图,我觉得特别棒

    二项式的系数公式:
    ((x+y)^n=C_n^0x^ny^0+C_n^1x^{n-1}y^1+......+C_n^nx^0y^n)
    (可以看到,其实也可以用杨辉三角表示)
    综合起来就是

    ((x+y)^n=sum_{k=0}^n imes C_n^k imes x^{n-k} imes y^k)

    错排问题

    错排就是诸如有1~n n个人,每个人按照1~n进行编号,现在要让他们排成一队,但是每个人不能在自己编号上的问题。

    对于这个问题,luogu日报已经有专门的一期来进行详细的讲解~~
    传送门——戳我~~

    错排的递推公式:
    (dp[1]=0)
    (dp[2]=1)
    (dp[i]=(n-1)(dp[i-1]+dp[i-2]))

    圆排

    从n个不同元素中不重复地取出m(1≤m≤n)个元素在一个圆周上,叫做这n个不同元素的圆排列。如果一个m-圆排列旋转可以得到另一个m-圆排列,则认为这两个圆排列相同。

    n个不同元素的m-圆排列个数N为:
    (A_n^m/m=frac{n!}{(n-m) imes m})
    特别地,当m=n时,n个不同元素作成的圆排列总数N为: (N=(N-1)!)

    环上的染色问题

    现在一个环被分成了n段,要求每一段上都涂上颜色。一共有k种不同的颜色,涂好之后两两相邻颜色不能相同。问有多少种涂色方案?

    这个问题我们可以这样考虑:
    第一种情况:如果我们把原先的环看作只有(n-1)段,进行涂色,那么就是子问题(A_{n-1}),而且因为现在两两相邻的一定颜色不同,所以这时候我们再添加一个的话就是乘上(m-2)
    第二种情况:我们把原先的环看作(n-2)段,,这样的话转换成了(A_{n-2})的子问题,然后我们随意将一段分为两段,这时候还差一段,在两个相同颜色中间插入一种颜色,自然是有(m-1)种选择方法。
    递推公式整理如下:

    (A_n=(m-2)A_{n-1}+(m-1)A_{n-2})

    这是一个二阶常系数递推式,推导之后通项公式如下:

    (A_n=(m-1)^n+(-1)^n imes (m-1))

    求组合数:

    1、如果p是质数而且比较小((<=10^5)),可以使用lucas定理
    2、如果(n,m<=10^6,p<=10^9) 可以先预处理出来逆元,然后直接算qwq

    补充杨辉三角中的一个求斜列和的公式:

    (C_n^i+C_{n+1}^i+...+C_{m}^i=C_{m+1}^{i+1}-C_{n}^{i+1})
    具体就是可以把右边的那个减数转移到左边来。。其他的合并很直观了qwq

  • 相关阅读:
    public interface IBaseService<T> where T:class, new()含义
    mvc多条件查询
    jquery select下拉框和 easy-ui combox 选定指定项区别
    .net 中主框架的搭建(2种方式)
    linq ->sql & linq->lambda中的cud
    mvc中日志的原理和使用步骤
    Sprint.Net和Mvc结合使用
    2017.5.12总结
    c#前端验证和后台验证总结
    matlab根据url链接下载*.tar文件并解压
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9687162.html
Copyright © 2011-2022 走看看