從今天開始,每天練習一道演算法題,今天是第一題-----放蘋果。
把M個同樣的蘋果放在N個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?(用K表示)5,1,1和1,5,1 是同一種分法。
第一行是要輸入的測試資料的數目t(0 <= t <= 20)。以下均包含二個整數M和N,以空格分開。1<=M,N<=10。
對輸入的每組資料M和N,用一行輸出相應的K。
輸入:
1 7 3(1表示輸入一組資料)
輸出:8
輸入:
2 8 4 7 3(2表示輸入兩組資料)
輸出:
15
8
設f(m,n) 為m個蘋果,n個盤子的放法數目,則先對n作討論,
當n>m:必定有n-m個盤子永遠空著,去掉它們對擺放蘋果方法數目不產生影響。即if(n>m) f(m,n) = f(m,m)
當n<=m:不同的放法可以分成兩類:
1、有至少一個盤子空著,即相當於f(m,n) = f(m,n-1);
2、所有盤子都有蘋果,相當於可以從每個盤子中拿掉一個蘋果,不影響不同放法的數目,即f(m,n) = f(m-n,n).
而總的放蘋果的放法數目等於兩者的和,即 f(m,n) =f(m,n-1)+f(m-n,n)
遞迴出口條件說明:
當n=1時,所有蘋果都必須放在一個盤子裡,所以返回1;
當沒有蘋果可放時,定義為1种放法;
遞迴的兩條路,第一條n會逐漸減少,終會到達出口n==1;
第二條m會逐漸減少,因為n>m時,我們會return f(m,m) 所以終會到達出口m==0.
import java.util.Scanner;public class TheApple {public static void main(String args[]) {int t, m, n;Scanner in = new Scanner(System.in);t = in.nextInt() + 1;while ((t = t - 1) > 0) {m = in.nextInt();n = in.nextInt();System.out.println(fun(m, n));}}static int fun(int m, int n) // m個蘋果放在n個盤子中共有幾種方法{if (m == 0 || n == 1) // 因為我們總是讓m>=n來求解的,所以m-n>=0,所以讓m=0時候結束,如果改為m=1,return 1; // 則可能出現m-n=0的情況從而不能得到正確解if (n > m)return fun(m, m);elsereturn fun(m, n - 1) + fun(m - n, n);}}
參考:http://www.cnblogs.com/celia01/archive/2012/02/19/2358673.html
作者:jason0539
微博:
部落格:(轉載請說明出處)