【数论】排列组合问题
排列
定义:
从n个不同元素中,任取m(m≤n,m与n均为自然数,下同)个元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列;从n个不同元素中取出m(m≤n)个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数,用符号 A(n,m)表示
公式:
A(n,m)=n(n-1)*(n-2)*……*(n-m+1)= n!/(n-m)!
PS:此外规定0!=1
特殊排列:
- 不全相异元素的排列:
在n个元素中 n1个元素彼此相同 有n2个元素彼此相同......有nm个元素彼此相同 并且n1+n2+...+nm=n
其排列数公式为:n!/(n1!*n2!*...*nm!)
【引例】把3个相同的黄球 2个相同的蓝球 4个相同的白球排成一排 有(3+2+4)!/(3!*2!*4!)=1260
- 圆排列
从n个数中取m个 不分首尾地排成一个圆圈的排列叫做圆排列 方案数为A(n,m)/m=n!/(m*(n-m)!)
组合
定义:
从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。用符号 C(n,m) 表示
公式:
C(n,m)=A(n,m)/m!=n!/(m!(n-m)!) 因为多出了一个全排列需要删去
可重复组合:从n个元素中 取出r个元素组成一个组合 且允许这r个重复使用 记为H(n,r)=C(n+r-1,r)
性质:
- C(n,m)=C(n,n-m) 规定:C(n,0)=C(n,n)=1
- C(n+1,m)=C(n,m)+C(n,m-1) 杨辉三角递推
二项式定理:
(a+b)n=Σni=0C(n,i)a(n-i)bi
二项式系数:C(n,i) 运用杨辉三角
【例题】洛谷P1313 [NOIP2011TG]计算系数:https://www.luogu.org/problemnew/show/P1313
题解链接:https://www.cnblogs.com/BrokenString/p/9665237.html
Lucas定理
定义:
Lucas(n,m,p)=C(n%p,m%p)* Lucas(n/p,m/p,p)
Lucas定理是用来求C(n,m) mod p的值,p是素数。

#include<iostream> #include<cstdio> using namespace std; #define LL long long LL T,n,m,p; LL quickpow(LL a,LL b) { LL ret=1; while(b) { if(b&1) ret=ret*a%p; a=a*a%p; b>>=1; } return ret; } LL C(LL n,LL m) { if(m>n) return 0; LL a=1,b=1; for(LL i=n-m+1;i<=n;i++) a=a*i%p;//计算n!/(n-m)! for(LL i=2;i<=m;i++) b=b*i%p;//计算1/m! return a*quickpow(b,p-2)%p;//费马小定理求逆元 } LL Lucas(LL n,LL m) { if(!m) return 1; else return (C(n%p,m%p)*Lucas(n/p,m/p))%p;//递推公式 } int main() { scanf("%lld",&T); while(T) { T--; scanf("%lld%lld%lld",&n,&m,&p); printf("%lld\n",Lucas(n,m)); } }
Catalan数列
定义:
给定n个0和n个1,它们按照某种顺序排成长度为2n的序列 满足任意前缀中0的个数都不少于1的个数的序列数量为:Catn=C(2n,n)/(n+1)
有关题目:
- n个左括号和n个右括号组成的合法括号序列数量为Catn
- 1,2...n经过一个栈 形成合法的出栈顺序数量为Catn
- n个节点构成的不同二叉树的数量为Catn
- 在平面直角坐标系上 每步只能向上或者向右走 从(0,0)到(n,n)并且除两个端点外不接触直线y=x的路线数量为2Catn
- 在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)
- n层的阶梯切割为n个矩形的切法数
这里给出一个较为详细的dalao的blog:https://blog.csdn.net/duanruibupt/article/details/6869431
小技巧:
如果看到
n=1,answer=1;
n=2,answer=2;
n=3,answer=5;
n=4,answer=14;
n=5,answer=42;
基本可以往卡特兰数方面想..
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步