错排问题 xmu 1052.False

来源:互联网 发布:传智php教程百度云 编辑:程序博客网 时间:2024/05/20 13:17

定义: n个有序的元素应有n!个不同的排列,如若一个排列使得所有的元素不在原来的位置上,则称这个排列为错排,有的叫重排。

1 2 3 4的错排有

4 3 2 1,4 1 2 3,4 3 1 2,

3 4 1 2,3 4 2 1,2 4 1 3,

2 1 4 3,3 1 4 2,2 3 4 1。

第一列是4分别与1,2,3互换位置,其余两个元素错排.由此生成的。

第2列是4分别与3,1,2(123的一个错排)的每一个数互换而得到的。即

4 1 2 3,3 4 2 1 ,3 1 4 2

第三列则是由另一个错排231和4换位而得到,即

4 3 1 2, 2 4 3 1 ,2 3 4 1

 

n个数1,2,…,n错排的数目为Dn, 任取其中一数i 数i分别与其他的n-1个数之一互换,其余

n-2个数进行错排,共得(n-1)Dn-2个错排。另一部分为数i以外的n-1个数进行错排,然后i与其中每个数互换,得(n-1)Dn-1个错排。

综合以上分析结果得递推关系

Dn=(n-1)(Dn-1+Dn-2), D1=0,D2=1     

 

以上是一个网站上给出的解答,但是我一直在想这是怎么解决重复问题呢?也就是说怎么才能保证这样的递推是没有重复的。现在我想通了,我们可以这样理解,对第n个数,如果是n-1个数原本符合要求,那么第n个数和前n-1个数都交换一次即可,这是一种情况。也可以是在前n-1个数中有一个数不是错排的,即对i数的排列还是在第i个位置上,这时只要把i和n交换也满足了条件,这是第二种情况。这样来理解就方便多了!         

这类型的题的应用也是很广泛的,如:N个人从一个箱子中抽取自己的名字,如果抽取到了,就是胜利者,这个时候没有胜利者的情况有多少种;还有就是N个新郎去找自己的新娘,问有M对找错的情况是多少;等等,这些都是错排问题,n个人错排的情况是多少就是上面的公式:f(n) = (n-1)(f(n-1)+f(n-2));




  1. import java.io.BufferedInputStream;  
  2. import java.math.BigInteger;  
  3. import java.util.Scanner;  
  4.   
  5. public class Main {  
  6.   
  7.     /** 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) {  
  11.         Scanner scan=new Scanner(new BufferedInputStream(System.in));  
  12.         BigInteger[] ans=new BigInteger[1005];  
  13.         ans[1]=BigInteger.ZERO;  
  14.         ans[2]=BigInteger.ONE;  
  15.         ans[3]=BigInteger.valueOf(2);  
  16.         for(int i=4;i<=1000;i++){  
  17.             ans[i]=(ans[i-1].add(ans[i-2])).multiply(BigInteger.valueOf(i-1));  
  18.         }  
  19.         int t=0;  
  20.         while(true){  
  21.             int n=scan.nextInt();  
  22.             if(n==0)  
  23.                 break;  
  24.             t++;  
  25.             System.out.println("Case"+" "+t+":");  
  26.             System.out.println(ans[n]);  
  27.         }  
  28.     }  
  29.   
  30. }