首页 > 其他分享 >排列组合学习笔记

排列组合学习笔记

时间:2023-03-02 21:23:50浏览次数:48  
标签:int sum 元素 笔记 学习 leq 排列组合 binom mod

以下部分内容摘自OI Wiki

排列数

从 \(n\) 个数中选出 \(m\) 个数按照一定的顺序排列,用 \(A_{n}^{m}\) 表示。排列的计算公式如下:

\(A_{n}^{m}=n(n-1)(n-2)...(n-m+1)=\dfrac{n!}{(n-m)!}\)。

组合数

从 \(n\) 个不同的元素中,选出 \(m\) 个元素组成一个集合,用 \(C_{n}^{m}\) 表示,也常用 \(\binom{n}{m}\) 表示。组合的计算公式如下:

\(C_{n}^{m}=\dfrac{n!}{m!(n-m)!}\)。

特别地,当 \(m>n\) 时,\(A_{n}^{m}=C_{n}^{m}=0\)。

插板法

插板法(Stars and bars)是用于求一类给相同元素分组的方案数的一种技巧,也可以用于求一类线性不定方程的解的组数。

正整数和的数目

问题一:现有 \(n\) 个 完全相同的元素,要求将其分为 \(k\) 组,保证每组至少有一个元素,一共有多少种分法?

这个问题的本质就是求 \(x_1+x_2+...+x_k=n\) 的正整数解的组数。

考虑在这些元素的 \(n-1\) 个空隙中插入 \(k-1\) 块板子,因为元素完全相同,那么答案就是 \(\binom{n-1}{k-1}\)。

非负整数和的数目

问题二:在问题一的基础上,允许每组元素为空。

本质就是求 \(x_1+x_2+...+x_k=n\) 的非负整数解的组数。

考虑先借来 \(k\) 个元素,在 \(n+k-1\) 个空隙中插入 \(k-1\) 个空格。最后再把借来的元素从每组中删去,即可满足题意。答案为 \(\binom{n+k-1}{k-1}\)。

不同下界整数和的数目

问题三:在问题二的基础上,要求第 \(i\) 组的元素数量至少为 \(a_i\),满足 \(\sum a_i \leq n\)。

即求满足 \(x_i \geq a_i\),\(x_1+x_2+...+x_k=n\) 的解的组数。

类比问题二,第 \(i\) 组先借来 \(a_i\) 个元素,令 \(x_i'=x_i-a_i\),那么就有 \(x_i' \geq 0\)。得到新方程:

\(x_1'+x_2'+...+x_k'=n-\sum a_i\)。

那么问题转为求这个方程的非负整数解的组数。答案为 \(\binom{n-\sum a_i+k-1}{k-1}\)。

不相邻的排列

问题四:从 \(1 \sim n\) 中选 \(k\) 个不相邻的数,求方案数。

设第 \(i\) 个数与第 \(i-1\) 个数的间隔为 \(x_i\),其中 \(x_1\) 表示第一个元素与 \(0\) 的间隔,\(x_{k+1}\) 表示最后一个元素与 \(n+1\) 的间隔。于是 \(x_1 \geq 0,x_{k+1} \geq 0\),\(x_i \geq 1(i=2,3,4...k)\)。得到方程:

\(x_1+x_2+...+x_{k+1}=n-k\)。

令 \(x_1'=x_1+1\),\(x_{k+1}'=x_{k+1}+1\)。

那么就转化为了问题一。答案就是 \(\binom{n-k+1}{k}\)。

二项式定理

\((a+b)^n=\sum_{i=0}^{n}\binom{n}{i}a^ib^{n-i}\)、

组合数的性质:

将选出的集合对全集取补集,数值不变:

\(\binom{n}{m}=\binom{n}{n-m}\) 。 \((1)\)

根据定义可以推出:

\(\binom{n}{k}=\frac{n}{k} \binom{n-1}{k-1}\) 。 \((2)\)

用杨辉三角的表达式,可以推出:

\(\binom{n}{m}=\binom{n-1}{m-1}+\binom{n-1}{m}\)。 \((3)\)

取二项式定理中 \(a=b=1\) 的特殊情况,可以得到:

\(\binom{n}{0}+\binom{n}{1}+...+\binom{n}{n}=\sum_{i=0}^{n} \binom{n}{i}=2^n\)。\((4)\)

同理,取二项式定理中 \(a=1,b=-1\) 的特殊情况,可以得到:

\(\sum_{i=0}^{n}(-1)^i\binom{n}{i}=[n==0]\)。\((5)\)

拆式子,感性理解一下可以得到:

\(\sum_{i=0}^{m} \binom{n}{i} \binom{m}{m-i}=\binom{n+m}{m}\)。\((6)\)

取 \((6)\) 中 \(n=m\) 的特殊情况,可以得到:

\(\sum_{i=0}^{n} \binom{n}{i}^2=\binom{2n}{n}\)。\((7)\)

通过对 \((4)\) 所对应的多项式函数求导,可以得到:

\(\sum_{i=0}^{n} i \binom{n}{i}=n2^{n-1}\)。\((8)\)

在 \(1\sim {n+1}\) 中选出 \(k+1\) 个元素,可以考虑枚举最大的元素的值,那么就得到等式:

\(\sum_{i=0}^{n} \binom{i}{k}=\binom{n+1}{k+1}\)。\((9)\)

在 \(n\) 个元素中选取 \(r\) 个元素,再在 \(r\) 中选取 \(k\) 个元素,等价于先选 \(k\) 个元素,再在剩下的 \(n-k\) 个元素中选取 \(r-k\) 个元素:

\(\binom{n}{r}\binom{r}[k]=\binom{n}{k}\binom{n-k}{r-k}\)。\((10)\)

而从杨辉三角上也不难发现:

\(\sum_{i=0}^{n}\binom{n-i}{i}=F_{n+1}\)。

其中 \(F\) 为斐波那契数列。

组合数问题

\(T\) 组询问,给定 \(n,m\) 和 \(k\),对于所有的 \(0\leq i\leq n,0\leq j\leq \min \left ( i, m \right )\) 有多少对 \((i,j)\) 满足 \(k|\binom{i}{j}\)。

\(0 \leq n, m \leq 2 \times 10^3\),\(1 \leq T \leq 10^4\)。

思路

注意到 \(n,m\) 的范围,同时 \(k\) 对于每一组询问相同。可以考虑 \(O(nm)\) 预处理出答案,\(O(1)\) 询问。

根据组合数在模 \(k\) 意义下的递推公式:

\(\binom{i}{j} =\left\{\begin{matrix} (\binom{i-1}{j-1}+\binom{i-1}{j}) \mod{k},j\in[1,i] \\ 1,j=0 \end{matrix}\right.\)

如果 \(\binom{i}{j}\) 在模 \(k\) 意义下为 \(0\),那么显然就是一对满足题意的数对。只需要处理前缀和即可。

code:

#include<bits/stdc++.h>
using namespace std;
const int M=2e3+5;
int c[M][M],s[M][M],t,k,n,m;
int main()
{
    cin>>t>>k;
    for(int i=1;i<M;i++) c[i][0]=c[i][i]=1;
    for(int i=1;i<M;i++)
        for(int j=1;j<i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
    for(int i=1;i<M;i++)
    {
        for(int j=1;j<=i;j++)
        {
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
            if(c[i][j]==0) s[i][j]++;
        }
        s[i][i+1]=s[i][i];
    }
    while(t--)
    {
        cin>>n>>m;
        if(n<m) m=n;
        cout<<s[n][m]<<endl;
    }
}

回忆京都

\(q\) 次询问,每次询问求:

\(\sum_{i=1}^n \sum_{j=1}^m C^i_j\),其中当\(i>j\)的时候,钦定\(C^i_j\)为\(0\)

\(1 \leq q \leq 10000,1 \leq n,m \leq 1000\)。

思路

可以直接预处理出 \(n,m\) 范围内的组合数,再用前缀和来统计答案。那么就是 \(O(nm)\) 预处理,单次询问的复杂度为 \(O(1)\)。

但我们也可以利用上面得到的等式 \((9)\),对原式进行变换:

\(\sum_{i=1}^n \sum_{j=1}^m \binom{j}{i}=\sum_{i=1}^{n} \binom{m+1}{i+1}\)。

那么也可以做到 \(O(qn)\) 。

code:

#include<cstdio>
using namespace std;
const int mod=19260817,N=1050;
int c[N][N],s[N][N],n,m,q;
int main()
{
	for(int i=0;i<N;i++)
	    for(int j=0;j<=i;j++)
	        if(!j) c[i][j]=1;
	        else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
	for(int i=1;i<N;i++) for(int j=1;j<N;j++) s[i][j]=(s[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1]+c[i][j]+mod)%mod;
	scanf("%d",&q);
	while(q--)
	{
		scanf("%d%d",&m,&n);printf("%d\n",s[n][m]);
	}
	return 0;
}

Lucas定理

对于质数 \(p\),有:

\(\binom{n}{m} \mod {p}=\binom{\lfloor n/p \rfloor}{\lfloor m/p \rfloor}\binom{n \mod {p}}{m \mod {p}} \mod {p}\)

吉夫特

题意比较繁琐,可以看原题题面。

思路:

应用 Lucas 定理, \(\binom{a_i}{a_j} \mod {2}=\binom{\lfloor a_i/2 \rfloor}{\lfloor a_j/2 \rfloor}\binom{a_i \mod {2}}{a_j \mod {2}} \mod {2}\)。

对于后面的 \(\binom{a_i \mod {2}}{a_j \mod {2}}\),其取值有 \(\binom{1}{1},\binom{1}{0},\binom{0}{1},\binom{0}{0}\) 四种,其中只有 \(\binom{0}{1}=0\)。

不难发现,应用 Lucas 定理后就是将 \(a_i\) 与 \(a_j\) 在二进制下的每一位单独拎出来,为了避免出现 \(\binom{0}{1}\) 的情况,需要满足在二进制下,\(a_j\) 为 \(a_i\) 的子集。那么就可以用枚举子集的方法记录以每一个数结尾的方案数,最终的复杂度为 \(O(3^{\log_2 \max(a_i)})\)

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e5+10,mod=1e9+7;
int n,x,f[N],ans;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&x);
		for(int j=x-1&x;j;j=j-1&x) f[j]=(f[j]+f[x]+1)%mod;
		ans=(ans+f[x])%mod;
	}
	printf("%d\n",ans);
	return 0;
}

标签:int,sum,元素,笔记,学习,leq,排列组合,binom,mod
From: https://www.cnblogs.com/ListenSnow/p/17173565.html

相关文章

  • RangeNet++学习笔记
    RangeNet++方法(A)将输入点云转换为距离图像表示,即range图像;(B)2D图像完全卷积语义分割;(C)从原始点云中恢复所有点的从2D到3D的语义转换,无论使用的距离图像离散......
  • 大型数据库技术架构阅读笔记--性能
    常见的性能指标有如下:1、响应时间    简称RT,指的是客户发出请求到得到系统响应的整个过程的时间。也就是用户从客户端发起一个请求开始,到客户端接收到从服务器端......
  • 阅读笔记《大型网站技术架构核心原理与案例分析》《高性能网站建设指南》
    软工三班王骜我们组的主题是性能。直观的说法就是网站的响应速度,它不仅仅是网站打开速度。网站性能涉及用户访问网站的整个流程中。首先用户在浏览器端发出请求,其次在......
  • Data Shapley : 机器学习数据的公平估值 ICML2019 斯坦福大学
    本篇论文的贡献提供了在机器学习中公平地评估数据的一个公式,利用博弈论提出了数据的Shapley值来量化单个数据点对学习任务的贡献。DataShapley唯一地满足公平估值的三个自......
  • 软件工程学习第十天
        今天我拿出格外的半小时继续学习css。今天学的是css的外边距和填充。    在css中用margin属性定义元素周围的空间,margin可以单独改变元素的上,下,左,右......
  • 学习操作系统P4 理解并发程序执行 (Peterson算法、模型检验与软件自动化工具)
    啊 多一个线程,在状态机里也可以理解为多一个栈帧啊啊啊错误如下图所示啊啊  当只有一个人想上厕所时,只有一个旗子被举起来,因此举旗的人可以直接进厕所......
  • android 逆向笔记
    壳检测工具GDA2.逆向分析APP一般流程1.使用自动化检测工具检测APP是否加壳,或者借助一些反编译工具依靠经验判断是否加壳2.如果apk加壳,则需要先对apk进行脱壳......
  • 大型网站技术架构阅读笔记--性能测试章节
    1.由于网站响应通常很快,很难精确测量一次响应时间,在测试网站响应时间时,可以类比测纸张厚度的方法,取一万次响应的总时间,然后除以一万来得到结果,,同时测试程序本身也会占......
  • 阅读笔记
    可修改性指系统或者软件能够快速的以较高的性价比对系统进行变更的能力,可修改性战术的目标是控制实现、测试和部署变化的时间的成本。就比如说《大型网站技术架构:核心原理......
  • c语言学习记录 冒泡排序
    #include<stdio.h>#include<string.h>#define_CRT_SECURE_NO_WARNINGS1voidbubble_sort(intarr[],intsz){ inti=0; //排序次数 for(i=0;i<sz-1;i+......