2072 Problem F 放蘋果
阿新 • • 發佈:2018-12-04
問題 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; }