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]; }
相关文章
相关标签/搜索