首页 > 其他分享 >错排数

错排数

时间:2023-03-09 16:14:25浏览次数:47  
标签:10 排列 排数 int 位置 leq 错排

定义

考虑一个有 \(n\) 个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。 \(n\) 个元素的错排数记为 \(D_n\)。

对于情况较少的排列,可以使用枚举法。

当 \(n=1\) 时,全排列只有一种,不是错排,\(D_1 = 0\)。

当 \(n=2\) 时,全排列有两种,即 \(1、2\) 和 \(2、1\),后者是错排,\(D_2=1\)。

当n=3时,全排列有六种,其中只有 \(3、1、2\) 和 \(2、3、1\) 是错排,\(D_3=2\)。用同样的方法可以知道 \(D_4=9\)。

最小的几个错排数是:\(D_1 = 0,D_2 = 1,D_3=2,D_4 = 9,D_5 = 44,D_6 = 265,D_7 = 1854\)。

递推式:

考虑对于一个数 \(n\),放在了第 \(i\) 个位置,那么 \(i\) 这个数就可以放在 \(n\) 位置,或者除了 \(i,n\) 以为的任意一个位置。

(1)\(i\) 放在了 \(n\) 位置,那么剩下的 \(n-2\) 个数的排列方法就是 \(D_{n-2}\)。

(2)\(i\) 不放在 \(n\) 位置,那么 \(i\) 就有 \(n-2\) 个位置可以去,其余的所有元素也都有 \(n-2\) 个位置可以去,那么就成为了 \(n-1\) 个元素的错排问题,方案数为 \(D_{n-1}\)。

而这样的 \(i\) 一共有 \(n-1\) 个,所以最终的递推式就是:

\(D_{n}=(n-1)\times (D_{n-1}+D_{n-2})\)。

排列计数

求有多少种 \(1\) 到 \(n\) 的排列 \(a\),满足序列恰好有 \(m\) 个位置 \(i\),使得 \(a_i = i\)。

答案对 \(10^9 + 7\) 取模。

\(1 \leq n \leq 10^6\),\(0 \leq m \leq 10^6\)。

思路:

排列中有 \(m\) 个位置在原位置上,那么也就是有 \(n-m\) 个数不在原位置上,这部分的方案数就是 \(D_{n-m}\),而选取这 \(m\) 个位置的方案数为 \(\binom{n}{m}\),所以最终的答案为:

\(Ans=\binom{n}{m} D_{n-m}\)。

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
const int N=1e6+10;
int fac[N],infac[N],inv[N],n,m,T,d[N];
void init()
{
	fac[0]=infac[0]=inv[0]=fac[1]=infac[1]=inv[1]=1;d[1]=0;d[2]=1;
	for(int i=2;i<N-1;i++)
	{
		d[i+1]=1ll*i*(d[i]+d[i-1])%mod;
		fac[i]=1ll*i*fac[i-1]%mod;
		inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
		infac[i]=1ll*infac[i-1]*inv[i]%mod;
	}
}
int C(int n,int m){return 1ll*fac[n]*infac[m]%mod*infac[n-m]%mod;}
int main()
{
	init();
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		if(n==m) puts("1");
		else printf("%d\n",(1ll*C(n,m)*d[n-m]%mod+mod)%mod);
	}
	return 0;
}

标签:10,排列,排数,int,位置,leq,错排
From: https://www.cnblogs.com/ListenSnow/p/17198838.html

相关文章

  • 重排数字的最小值
    给你一个整数num。重排num中的各位数字,使其值最小化且不含任何前导零。返回不含前导零且值最小的重排数字。注意,重排各位数字后,num的符号不会改变。/***@p......
  • LC[386] 字典序排数
    https://leetcode.cn/problems/lexicographical-numbers/description/想像成一颗树的遍历AC代码:classSolution{public:vector<int>lexicalOrder(intn){......
  • 错排数计数
    定义:\(\foralli\in[1,n],p_i\neqi\)的长度为\(n\)的排列数。一开始看到的时候还想用容斥推:\(\sum\limits_{i=0}^n\binom{n}{i}(-1)^i(n-i)!\),结果发现太垃圾了。递......