openjudge-1664 放蘋果
總時間限制:
1000ms
記憶體限制:
65536kB
描述
把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
樣例輸出
8
這個題目採用遞迴解決,我們首先對於問題分析一下,如果盤子的數目大於蘋果的數目,那肯定要有一些盤子是什麼也不放的。
所以還剩下 n-m 個盤子,其餘的盤子都是一樣的,所以不做處理。
然後對問題進行分類,要麼就有盤子不放蘋果,要麼就在每個盤子上面全放上蘋果。
對於這兩種情況:不放蘋果的話就 return f(m,n-1),然後這個遞迴就會從盤子數目從1到n-1遞迴求解有多少種 方案數。
這個過程實際上是先求當前的 有的不放 + 所有都放 的情況,然後要求這個就要先求之前的 有的不放 + 所有都放 的數目,直到回到遞迴的邊界條件得到一個確定的值,這時候邊界的值就知道了,是一個確定的數,那上一層的遞迴就也可以通過一個確定的數相加得到確定的值,假設上一層是有兩個遞迴的的,,一個 有的不放 ,一個 所有都放 。所以最底層的邊界就要有四個值,每個遞迴兩個。其實這樣的話,這一層就已經相當於是最頂層了,這就是要求的結果了,因為,每次遞迴下去都是二層遞迴, 所以當遞迴數目為2的時候,就是最頂層了。
至於所有都放,自己體會一下。
說完了問題的分類,就該說遞迴的終止了,因為題目允許盤子不放入蘋果,所以,當蘋果數目為零,但是盤子數目不為零的時候,他的方案數就為 1 。
但是當盤子的數目為零的時候,就沒有方案數了,就是零。
注意遞迴的求解就是一定要有邊界條件。
#include <iostream> using namespace std; int f(int m,int n) { if (n>m) return f(m,m); if (m==0) return 1; if (n==0) return 0; return f(m,n-1)+f(m-n,n); } int main() { int t; int m,n; cin>>t; while (t--) { cin>>m>>n; cout<<f(m,n)<<endl; } return 0; }