1 package acknowledge;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6  * ABCDE,五个人,已按顺序排好,现在重新排队,要求每个人都不排到原来的位置上,问有多少种排法
 7  * 
 8  * @author HHY 扩展:有N个人排队,现在重新排队,每个人都不排到原来的位置上,问有多少中排法? 
 9  * 用 f(n) 表示n个人有多少种排法 理解思路:
10  *     1. 已知f(1) = 0, f(2) = 1 
11  *     2. n = 3 时,不做限制有 3! 种排法 
12  *         1个人站在原位,有 C(3,1) * f(2) 种排法
13  *         2个人站在原位,有 1 种排法 则 f(3) = 3! - C(3,1)*f(2) - 1 
14  *     3. n = 4时,不做限制有 4! 种排法 
15  *         1个人站在原位,有 C(4,1) * f(3) 种排法 
16  *         2个人站在原位,有 C(4,2) * f(2)种排法 
17  *         3个人站在原位,有 1 种排法 
18  *         则 f(4) = 4! - C(4,1) * f(3) - C(4,2) * f(2) - 1
19  *     4. n = k 时,不做限制有 k! 种排法 1个人站在原位,有 C(k,1) * f(k-1) 种排法 
20  *            2个人站在原位,有 C(k,2) * f(k-2) 种排法 
21  *            。。。 
22  *         k-1个人站在原位,有 1 种排法 
23  *         则 f(k) = k! - C(k,1) * f(k-1) - ... - C(k, k-2) * f(2) -1
24  */
25 public class GetNoRepeatSort {
26 
27     /**
28      * 求n的阶乘
29      * 
30      * @param n
31      * @return
32      */
33     public static int getMultiN(int n) {
34         int k = n;
35         for (int i = n - 1; i > 0; i--) {
36             k *= i;
37         }
38         return k;
39     }
40 
41     /**
42      * 求C(n,k) = n! / k!(n-k)!
43      * 
44      * @param n
45      * @param k
46      * @return
47      */
48     public static int getC(int n, int k) {
49         int mulN = getMultiN(n);
50         int mulk = getMultiN(k);
51         int mul = getMultiN(n - k);
52         return mulN / (mulk * mul);
53     }
54 
55     /**
56      * f(n) = n! - C(n,1) * f(n-1) - ... - C(n,k) * f(n-k) - ... - C(n,n-2)*f(2) - 1
57      * 
58      * @param n
59      * @return
60      */
61     public static int getSortNum(int n) {
62         if (n <= 1)
63             return 0;
64         if (n == 2)
65             return 1;
66         int sub = 1;
67         for (int k = 1; k <= n-2; k++) {
68             sub += getC(n, k) * getSortNum(n - k);
69         }
70         return getMultiN(n) - sub;
71     }
72 
73     public static void main(String[] args) {
74         System.out.println("Input a integer:");
75         Scanner sc = new Scanner(System.in);
76 
77         int n = sc.nextInt();
78         System.out.println("SortNum: " + getSortNum(n));
79     }
80 }