n我的排隊都不站在原來的位置

1、題目描述

有n我的首先站成一排,請問,當n我的第二次再從新排列,每一個人都不在原來的位置上,問有多少種站法。例如,原來有3我的,ABC,那麼第二次每一個人都不在原來的位置上有2種站法,BCA和CAB,這題實際上是一道數學題,考察排列組合的知識。數組

解題思路:假設有n我的,咱們的問題規模設爲A(n),A(n)表明n我的都不在原來的位置上一共有多少種站法。令第1我的站在非1號位置,一共有n-1種站法,假設第1我的站在2號位置,那麼第2我的的站的位置分2類:第一類是第2我的站在1號位置,這樣第1我的和第2我的的位置都肯定了,那麼剩下n-2個位置,問題規模變成了A(n-2),至關於第3我的不站在3號位置,第4我的不站在4號位置.....第n我的不站在n號位置第二類是第2我的不是站在1號位置,那麼問題的規模又變成了A(n-1),至關於第2我的不站在1號位置,第3我的不站在3號位置,第4我的不站在4號位置......第n我的不站在n號位置。因此A(n) = (n-1) * ( A(n-1) + A(n-2) ),這樣解題的思路就清晰了,只須要定義一個數組arr[n + 1],首先保存arr[1] = 0,arr[2] = 1,從arr[3]開始,迭代計算 arr[i] = (i - 1) * (arr[i - 1]  + arr[i - 2]),最後返回arr[n]就好了,也能夠定義三個變量分別保存arr[1],arr[2],arr[3],而後交替賦值,這樣能節省空間。爲了清晰,我仍是以定義數組來演示程序。spa

2、代碼演示

/** * n我的原來站成一排,從新再排一次,要求每一個人都不能 * 站在原來的位置,求有多少種站法。 * @param n */
    public static int fun(int n) { if(n <= 1) return 0; if(n == 2) return 1; int[] arr = new int[n + 1]; arr[1] = 0; arr[2] = 1; for(int i = 3; i <= n; i++) { arr[i] = (i - 1) * (arr[i - 1] + arr[i - 2]); } return arr[n]; }
相關文章
相關標籤/搜索