poj1664放苹果(递归)

题目链接http://poj.org/problem?id=1664

放苹果
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 37273   Accepted: 22957

Description

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

Input

第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

Output

对输入的每组数据M和N,用一行输出相应的K。

Sample Input

1
7 3

Sample Output

8


解题思路:就是n个球放m个盒子的问题,采用递归的思想,定义函数func(n,m)为n个苹果放入m个盘子,可以分为两种情况:
第一种,当m>n, 则总会有m-n个盒子空着,去掉他们对总的放法不产生影响,即 if(m > n) f(n, m) = f(n, n)
第二种,当n<=m时,可以分为两种:

  1.至少有一个盒子空着,则 f(n, m) = f(n, m-1);
  2.所有盒子都有球,我们可以从每个盒子中拿掉一个球而不影响总的放法,则 f(n, m) = f(n-m, m);
所以当n<=m时,f(n, m)=f(n, m-1) + f(n-m, m)

还有很多种不一样的n个球放入m个盒子的问题,这篇博客写的很详细:https://blog.csdn.net/zwz_511/article/details/46240927
递归出口的话看大佬解释的感觉很有道理,
递归出口条件说明:
        当m=1时,所有苹果都必须放在一个盘子里,所以返回1;
        当没有苹果可放时,定义为1种放法;
        递归的两条路,第一条m会逐渐减少,终会到达出口m==1;
        第二条n会逐渐减少,因为m>n时,我们会return func(n,n) 所以终会到达出口n==0

附上代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int ans,n,m;
 6 
 7 int func(int n,int m)
 8 {
 9     if(m==1||n==0) return 1;
10     if(m>n) return func(n,n);
11     return func(n,m-1)+func(n-m,m);
12 }
13 
14 int main()
15 {
16     int t;
17     cin>>t;
18     while(t--)
19     {
20         cin>>n>>m;
21         ans=func(n,m);
22         cout<<ans<<endl;
23     }
24     return 0;
25 }

 

猜你喜欢

转载自www.cnblogs.com/zjl192628928/p/9439674.html