目錄
1 問題描述
問題描述
每年冬天,北大未名湖上都是滑冰的好地方。北大體育組准備了許多冰鞋,可是人太多了,每天下午收工后,常常一雙冰鞋都不剩。
每天早上,租鞋窗口都會排起長龍,假設有還鞋的m個,有需要租鞋的n個。現在的問題是,這些人有多少種排法,可以避免出現體育組沒有冰鞋可租的尷尬場面。(兩個同樣需求的人(比如都是租鞋或都是還鞋)交換位置是同一種排法)
每天早上,租鞋窗口都會排起長龍,假設有還鞋的m個,有需要租鞋的n個。現在的問題是,這些人有多少種排法,可以避免出現體育組沒有冰鞋可租的尷尬場面。(兩個同樣需求的人(比如都是租鞋或都是還鞋)交換位置是同一種排法)
輸入格式
兩個整數,表示m和n
輸出格式
一個整數,表示隊伍的排法的方案數。
樣例輸入
3 2
樣例輸出
5
數據規模和約定
m,n∈[0,18]
問題分析
問題分析
2 解決方案
2.1 遞歸法
共有m個人還鞋,n個人借鞋,記最終排列數為f(m, n)。
現在求m和n的排隊情況,具體理解如下:
起始,要去一人還鞋(PS:此時,m = m - 1),還完后,可以選一人還鞋(PS:m = m - 1)或者一人借鞋(PS:n = n - 1)。
那么,f(m , n) = f(m - 1, n) + f(m, n - 1)。這就是求取f(m, n)的遞推公式,那么輕易可知當m < n時,f(m, n) = 0;當n = 0時,f(m, 0) = 1。
具體代碼如下:
package com.liuzhen.systemExe; import java.util.Scanner; public class Main{ //m代表還鞋的人數,n代表借鞋的人數 public int getArrange(int m, int n) { if(m < n) return 0; if(n == 0) return 1; return getArrange(m - 1, n) + getArrange(m, n - 1); } public static void main(String[] args){ Main test = new Main(); Scanner in = new Scanner(System.in); // System.out.println("請分別輸入還鞋人數m和和借鞋人數n:"); int m = in.nextInt(); int n = in.nextInt(); System.out.println(test.getArrange(m, n)); } }
運行結果:
請分別輸入還鞋人數m和和借鞋人數n: 3 2 5 請分別輸入還鞋人數m和和借鞋人數n: 12 7 23256
2.2 遞推法
具體代碼如下:
package com.liuzhen.systemExe; import java.util.Scanner; public class Main{ //m代表還鞋的人數,n代表借鞋的人數 public int getArrange1(int m, int n) { int[][] result = new int[m + 1][n + 1]; //初始化元素全為0 for(int i = 1;i <= m;i++) { result[i][0] = 1; //當借鞋的人數為0時,排列只有一種情況 for(int j = 1;j <= n;j++) { if(i >= j) //當i小於j時,排列總數為0 result[i][j] = result[i - 1][j] + result[i][j - 1]; } } return result[m][n]; } public static void main(String[] args){ Main test = new Main(); Scanner in = new Scanner(System.in); // System.out.println("請分別輸入還鞋人數m和和借鞋人數n:"); int m = in.nextInt(); int n = in.nextInt(); System.out.println(test.getArrange1(m, n)); } }
運行結果:
請分別輸入還鞋人數m和和借鞋人數n: 12 7 23256 請分別輸入還鞋人數m和和借鞋人數n: 4 3 14
參考資料: