• poj1664 (递归)


    放苹果
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 31295   Accepted: 19742

    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

    思路:
    首先对于给定的m和n,我们一步步的分析他们的大小关系,然后抽象出一个结论。
    (1.1)如果m>n,也就是苹果的数量比盘子要多,则所有的可能性便是将所有苹果放在1个盘子的可能情况个数s1,2个盘子的可能情况个数s2...n个盘子的可能情况个数sn
    (1.2)如果m<=n,也就是苹果的数量比盘子要少,则所有可能性便是将所有苹果放在1个盘子的可能情况个数s1,2个盘子的可能情况个数s2...m个盘子的可能情况个数sn
    基于m和n的情况,我们便能理解main函数中的for循环和min(m,n)的含义了,后者其实就是找出苹果能分成的最大块数
    然后看f函数,它的含义是求将m个苹果正好分到x个盘子里,有几种可能性。那么它一共会面临3种情况
    (2.1)当m=x,也就是将m个苹果正好分到m个盘子里,那当然只有一种可能性了,就是一个盘子一个
    (2.2)当m>x,也就是苹果的数量多于盘子的数量,这里的分析是解决本题的关键。
    我们可以将m个苹果正好分到1个、2个、3个...x个盘子里,用一个循环变量i来表示这个数,那么我们在每个盘子占了一个位置之后,就会剩下m-i个苹果,那现在的问题不就转换成了剩下的这m-i个苹果正好分配到i个盘子里一共有集中可能分法么?于是我们的递归就出来了。
    (2.3)当m<x,也就是将m个苹果正好分到x个盘子里,而且x还大于m——这明显是不可能的,所以为0。举个例子,有3个苹果,让你正好分到5个盘子里,正好分到的意思是每个盘子至少一个,现在你能给我有几种分发?

    #include <iostream>
    using namespace std;

    int f(int m,int x) {//将数字m分成x个"条" if(m < x) return 0; else if(m == x) return 1; else { if(x == 1) return 1; int ans = 0; for(int i = 1;i <= x;i++) ans += f(m-x,i); return ans; } } int main() { int m,n; int t; cin>>t; while(t--) { cin>>m>>n; int ans = 0; for(int i = 1;i <= min(n,m);i++) ans += f(m,i); cout<<ans<<endl; } return 0; }
  • 相关阅读:
    JavaWeb
    List的三种遍历(转)
    Java中父类和子类集合互相转换(转)
    Day4
    Ubuntu20.04配置 ES7.17.0集群
    K8S中部署apisix(非ingress)
    使用 Flutter&&Hive&&Bloc 写一个待办小demo
    SQL多行数据分组后合并某个字段
    sql group 拼接字段
    Socket
  • 原文地址:https://www.cnblogs.com/immortal-worm/p/6034718.html
Copyright © 2020-2023  润新知