递归--放苹果
問題描述
把 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的情況其實和N=M的情況是一樣的。于是我就寫出了這個四不像的算法。我也不知道是什么東西,但是能出結果,還能AC。。。哈哈。?
后來想想,我的方法有點像是搜索的方式,DFS(Depth first search)。即我先把前面我說的那些條件(按蘋果數遞減放)設定好,然后DFS去搜索每個盤放蘋果的情況,當剩下最后一個盤的時候,就能得到一種情況。
#include <stdio.h>
int M,N,nSum;
void recursion(int nCount,int left,int prio)
{
??? int i;
??? if (nCount == N-1 )
??? {
??????? if (left <= prio) ?
??????? {
??????????? nSum++;
??????? }
??? }
??? else
??? {
??????? for (i =prio; i >= 0; i--)
??????? {
??????????? if (i <= left)? //當前的值必須小于剩下的蘋果數
??????????? {
??????????????? recursion(nCount+1,left-i,i);
??????????? }
??????? }
??? }
}
int main()
{
??? int t;
??? scanf("%d",&t);
??? while (t)
??? {
??????? t--;
??????? nSum=0;
??????? scanf("%d%d",&M,&N);
??????? if(N > M) N=M;
??????? recursion(0,M,M);
??????? printf("%d\n",nSum);
??? }
??? return 0;
}
其實真正的遞歸是這樣的,考慮兩種情況:
- 每個盤都放有蘋果。即每個盤已經放有蘋果,這時的情況和把剩下m-n個蘋果放到n個盤的情況是一樣的,f(m-n,n);
- 至少有一個盤不放蘋果。即把m個蘋果放到n-1個盤子。f(m,n-1);
當然必須考慮m<n時,此時和f(m,m)的情況是一樣的。
最后判斷程序的出口:當蘋果數量為0或者盤數只剩1那么就表明找到一種情況。
#include <stdio.h>int recursion(int m, int n)
{
??? if (m == 0 || n == 1) return 1;
??? if (m < n) return recursion(m,m);
??? return recursion(m,n-1) + recursion(m-n,n);
}
int main()
{
??? int m,n,t;
??? scanf("%d",&t);
??? while (t)
??? {
??????? t--;
??????? scanf("%d%d",&m,&n);
??????? printf("%d\n",recursion(m,n));
??? }
??? return 0;
}
/5/15 22:18
/5/15 22:18
總結
- 上一篇: 113道C语言题目
- 下一篇: 递归--整数划分问题