1. 程式人生 > >2072 Problem F 放蘋果

2072 Problem F 放蘋果

問題 F: 放蘋果

時間限制: 1 Sec  記憶體限制: 32 MB
提交: 29  解決: 25
[提交][狀態][討論版][命題人:外部匯入]

題目描述

把M個同樣的蘋果放在N個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?(用K表示)5,1,1和1,5,1 是同一種分法。

輸入

第一行是測試資料的數目t(0 <= t <= 20)。以下每行均包含二個整數M和N,以空格分開。1<=M,N<=10。

輸出

對輸入的每組資料M和N,用一行輸出相應的K。

樣例輸入

2
6 3
7 2

樣例輸出

7
4

提示

解題分析:
         設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.

#include<iostream>
using namespace std;

int f(int m, int n) {
	if (n == 1 || m == 0) return 1;
	if (n > m) return f(m, m);
	return f(m, n - 1) + f(m - n, n);//遞迴核心
}

int main() {
	int T, M, N;
	cin >> T;
	while (T--) {
		cin >> M >> N;
		cout << f(M, N) << endl;
	}
	return 0;
}