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 }