错排公式及其应用

什么是错排公式?
首先我们考虑一个问题,如果书架上有n本书,现在希望把每本书都放在不是原来的位置上,那么有几种放置的方法?
上面的问题就是错排问题。
现在,我么来解决:
首先,我们取一本位置在m位置上的书,现在m位置空出来了,现在要放在其他n-1个位置上,假设我们放在了位置k上,那么我们就把k位置上的书拿出来了,现在k位置空出来了,所以现在原本在k位置上的书要放在哪里呢,有两种选择,一种是放在原来的M位置上,还有一种是放在其他的n-2个位置的随便一个,现在我们分析这两种情况:
1:放在m位置上,那就相当于m位置上的书和K位置上的书交换了位置,所以接下来剩余的n-2本书就又回到了初始的状态,对这n-2本书进行错排;
结合开始的n-1中情况,所以这种情况种数为(n-1)*dp[n-2].
2:不放在m位置上,那就相当于原本这本书要放在M位置上,现在不放了,并且其他的n-2本书也不放在原来的位置上,那么现在就有n-1本书不能放在原来的位置上,所以这种情况就是dp[n-1],结合开始的情况,就是(n-1)*dp[n-1].

总:结合前面的两种情况,那么总的情况就有:(n-1)*(dp[n-2] + dp[n-1]).

这里有一道例题供大家参考
转眼毕业了,曾经朝夕相处的同学们不得不都各奔东西,大家都去了不同的城市开始新的生活。在各自城市居住了一段时间后,他们都感到了一些厌倦,想去看看其他人的生活究竟如何,于是他们都选择到另一个同学所在城市去旅游,并且希望旅游的城市各不相同,他们想知道有多少种不同的方案,可是数量实在太多了,他们无法计算出来,你能帮助他们吗。

输入格式
一个正整数 n(n\le 20)n(n≤20),表示人数。

输出格式
一个数,表示有多少不同的方案。

输出时每行末尾的多余空格,不影响答案正确性

样例输入复制
3
样例输出复制
2

这其实也就是进行错排操作,代码如下:

//@author:hairu,wu
//@from:ahut
#include<iostream>
using namespace std;

typedef long long ll;

int main(){
	int n;
	cin >> n;
	ll dp[100];
	dp[0]=0;
	dp[1]=0;
	dp[2]=1;
	for(int i=3;i<=n;i++){
		dp[i]=(i-1)*(dp[i-2]+dp[i-1]);
	}
	cout<<dp[n]<<endl;
	return 0;
}
发布了83 篇原创文章 · 获赞 3 · 访问量 1353

猜你喜欢

转载自blog.csdn.net/weixin_41296877/article/details/105254826