错位排列及有关例题
错位排列
对于n的一个排列。如果所有的 不等于 ,那么这个排列称为错位排列
求解方法
考虑递推
前个元素时如何进行状态转移?
(一)根据错位排列的定义,第个元素肯定不会放在自己的位置上,故第个元素的位置有种选择。
(二)对于剩下的个元素,选择其中任意一个元素。此时的位置有两种选择:
1. 放在第个元素的位置上,宏观上相当于与的位置互换了。而剩下的i-2个元素依然要求错位排列。方案数为
2. 不放在第个元素的位置上,则相当于剩下的个元素全部进行错位排列。方案数为
综上,我们可以得到
例题 选新娘
题目大意:一共有对新婚夫妇,其中有个新郎找错了新娘,求发生这种情况一共有多少种可能.
有个新郎找错了,意味着有且只有个人是错排,另外人都刚好恰合。于是先求出,表示长度为的序列的错排。
然而这样就完了吗?并没有,还要看看是哪个人。从个人中选个,也就是组合数,于是答案就是
/*By QiXingzhi*/ #include <cstdio> #define r read() #define Max(a,b) (((a)>(b)) ? (a) : (b)) #define Min(a,b) (((a)<(b)) ? (a) : (b)) using namespace std; typedef long long ll; #define int ll const int N = 100010; const int M = 1010; const int INF = 1061109567; inline int read(){ int x = 0; int w = 1; register int c = getchar(); while(c ^ '-' && (c < '0' || c > '9')) c = getchar(); if(c == '-') w = -1, c = getchar(); while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar(); return x * w; } int n,m; int f[30]; inline int JieCheng(int x){ int res = 1; for(int i = 2; i <= x; ++i) res *= i; return res; } inline int C(int m, int n){ return JieCheng(n) / (JieCheng(m) * JieCheng(n-m)); } #undef int int main(){ #define int ll n = r; m = r; f[1] = 0; f[2] = 1; for(int i = 3; i <= m; ++i){ f[i] = (i - 1) * (f[i-2] + f[i-1]); } printf("%lld",f[m] * C(m,n)); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)