/*****************************************************************
题目:放苹果问题。
输入n为要测试数据的数目,以下每行M(M>=1)和N(N<=10),表示M个相同苹果
和N个相同的盘子,求有多少中不同的放法。

******************************************************************
算法描述:当输入m=0时只有一种情况即所有盘子均为空。当n=1时也只有一种
情况,即全放在这一个盘子里。
其他情况下的m,n均可以化为一系列m-i个盘子n-1个苹果问题的和


/****************************递归函数*****************************
如 m=7 n=3:如果第一个盘子放1个,则剩下的为m=6,n=2,如果第一个放2个则
剩下的为m=5,n=2…………
所以m=7,n=3可分解为:(6,2)+(5,2)+(4,2)+(0,2)
而(6,2)又可化为:(5,1)+(4,1)+(3,1)+(0,1)=4
(5,2)=(3,1)+(0,1)=2
(4,2)=(0,1)=1
(0,2)=1

所以共有8种

m的值必须大于已经放入盘子的苹果数,否则会出现重复;
如:

m=7,n=3可分解为:(6,2)+(5,2)+(4,2)+(3,2)+(2,2)+(1,2)+(0,2)
而(6,2)又可化为:(5,1)+(4,1)+(3,1)+(2,1)+(1,1)+(0,1)=4
(5,2)=(3,1)+(2,1)+(1,1)+(0,1)=2
(4,2)=(1,1)+(0,1)=1
(0,2)=1

通过计算可得三个盘子放的苹果数为:
1……1……5$
1……2……4*
1……3……3
1……4……2*
1……5……1$
     .
  .
  .
很明显有重复的组合输出

#include<iostream.h>
*****************************************************************/
  int Dgetnum(int m,int n,int min)
  {
    int i;
 int k;
 if(m==0)
  return 1;
 if(n==1)
  return 1;
 k=0;
 for(i=min;i<=m;i++)
 {
  if((m-i)>=i||(m-i)==0)
    k=k+Dgetnum(m-i,n-1,i);
 }
 
 return k;
  }

/****************************主函数*******************************/
int main()
{
    int i,j,t,m,n;
 cin>>t;
 for(i=0;i<t;i++)
 {
  cin>>m>>n;
  cout<<Dgetnum(m,n,1)<<endl;
 }
 return 0;
}
/*****************************************************************/
版权所有:www.sinory.com
2005-7

 posted on 2005-07-22 22:54  James Cheung  阅读(1462)  评论(0)    收藏  举报