poj1664-放苹果(递归)


一,题意:
  M个苹果放在N个盘子里,允许有盘子空着,问共有多少种不同的分法。
二,思路:
  递归的思想求解:
    1,有反复执行的过程(调用本身)
      第一种情况n>m : 必定有 n-m 个盘子空着,去掉不影响。
      第二种情况n<=m :
        i,有至少一个盘子空着;
        ii,每个盘子都有苹果;
        总的放苹果的方法数为两者之和:
2,有跳出反复执行过程的条件(递归出口)
  当苹果放完或者只有一个盘子的时候
   *递归两条路:
    i,n会逐渐减少,最终到达出口 n==1 ;
    ii,m逐渐减少,因为n>m时,return work(m,m),所以终会到达出口 m==0;
三,步骤:
  1,if(n>m) work(m,n) = work(m,m) ;
   else
    i,work(m,n) = work(m,n-1);
    ii,work(m,n) = work(m-n,n);
   work(m,n) = work(m,n-1) + work(m-n,n);
  2,if(m==0||n==1) return 1;

 1 #include<iostream> 
 2 using namespace std;
 3 
 4 int work(int m , int n){
 5     if(m==0||n==1)
 6         return 1;
 7     if(n>m)
 8         return work(m,m);    
 9     else
10         return work(m,n-1)+work(m-n,n);
11 }
12 
13 int main(){
14     int t , m , n ;
15     cin>>t;
16     while(t--){
17         cin>>m>>n;
18         cout<<work(m,n)<<endl;
19     }
20     return 0;
21 } 
View Code

注意:
  1,递归就是在过程或函数里调用自身
  2,在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
  3,递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
  4, 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
要求:
  1,每次调用在规模上都有所缩小(通常是减半);
  2,相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
  3,在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

posted @ 2015-10-15 09:41  My_Sunshine  阅读(357)  评论(0编辑  收藏  举报