关于错排公式的推导与应用

错排问题,又称更列问题,是组合数学中的问题之一。对于它的研究最早可以追溯到十八世纪,当时他被数学家尼古拉·伯努利和欧拉研究,因此在历史上也被称为伯努利--欧拉的错装信封问题。这个问题有许多具体的版本,比如在写信时讲n封信装到n个不同的信封里,有多少种全部装错信封的情况?再比如n个人各写一张贺卡相互赠送,有多少种赠送方法?这些经典的题目都是典型的错排问题。

  相信看过上面对于错排问题的简单的介绍,大家也都对它有了一些初步的了解,归结起来,就是考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排,n个元素的错排数记为D(n)。那么对于这样的排列D(n)有多少种呢?我们一步一步进行分析:

  首先,对于D(n),有1~n这样n个元素错排,所以对于第一个元素①,它现在可能的位置有(n-1)个,倘若它在第k个元素的位置上,对于第k个元素而言,它所在的位置就有两种可能—第一种,它处在非第一个元素①位置上,所以对于接下来的排列就相当于是n-1个元素的错排,即D(n-1);第二种,它处在第一个元素①的位置上,所以在排列D(n)中有两个元素找到了位置,那么接下来的队列就相当于是n-2个元素的错排。因此,对于D(n)都有D(n)=(n-1)*(D(n-1)+D(n-2))【特殊的,D(1)=0,D(2)=1】

错排公式的应用:HDU-2048

AC代码:

package hdu经典100题;

import java.text.DecimalFormat;
import java.util.Scanner;
/**
 * 	使用错排公式f[n]=(n-1)*(f[n-1]+f[n-2])
 * 	@author Geek
 *	@version 1.0
 * 	@date 2018年8月11日 下午9:55:32
 *	@TextDemo I hava a acDream
 *	@copyright 
 *	@remark
 */
public class P2048 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int C = in.nextInt();
		DecimalFormat decimalFormat = new DecimalFormat("0.00%");
		double[] nums = new double[21];
		nums[2] = 1;
		nums[3] = 2;
		for (int i = 4; i < nums.length; i++) {
			nums[i] = (i-1)*(nums[i-1]+nums[i-2]);
		}
		while(C!=0) {
			int n = in.nextInt();
			double jc = 1;
			for (int i = 2; i < n+1; i++) {
				jc*=i;
			}
			System.out.println(decimalFormat.format(nums[n]/jc));
			C--;
		}
	}
}

参考博客

猜你喜欢

转载自blog.csdn.net/acDream_/article/details/81591596