牌型种树(小白解法与大佬解法,通过例子解释递归)
2020-05-11 04:10
471 查看
题目
牌型种数
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
题目分析(方法一)
分析题目,遇到这道题,第一反应就是每个人十三张牌,直接十三次循环,每张牌牌数少于四种,然后进行判断最后是不是十三张牌即可。因此第一种做法也就直接出来了。
代码实现(方法一)
[code]public static void main(String [] args) { int count =0; for(int n1=0; n1<=4; n1++){ for(int n2=0;n2<=4; n2++) { for(int n3=0;n3<=4; n3++ ) { for(int n4=0;n4<=4; n4++) { for(int n5=0;n5<=4; n5++) { for(int n6=0;n6<=4; n6++) { for(int n7=0;n7<=4; n7++) { for(int n8=0;n8<=4; n8++) { for(int n9=0;n9<=4; n9++) { for(int n10=0;n10<=4; n10++) { for(int n11=0;n11<=4; n11++) { for(int n12=0;n12<=4; n12++) { for(int n13=0;n13<=4; n13++) { int pai=n1+n2+n3+n4+n5+n6+n7+n8+n9+n10+n11+n12+n13; if(pai==13) { count ++; } } } } } } } } } } } } } } System.out.println(count); }
题目分析(方法二---引用大佬的)
采用递归方式,简化代码,并且让耗费的时间更少,只不过前提是要理解递归方法。
简谈递归(https://cloud.tencent.com/developer/article/1356049)
递归(Recursion)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法,其核心思想是分治策略。 递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。
例子一:求阶乘
[code]public static int factrial(int n){ if(n<1){ return 1; } return n*factrial(n-1); }
上面是网上大多数代码的例子,但是对于初学者来言,是不太友好的,因为看不到太多的细节,所以 我改造了一下,实现的是同样的功能,但有详细的步骤,如下:
[code]public static int factrialDetail(int n){ if(n<1){ System.out.println("拆解问题完毕,开始分而治之"); return 1; } System.out.println("f("+n+")="+n+" * f("+(n-1)+")"); int z= n*factrialDetail(n-1); System.out.println("f("+n+")="+z); return z; }
例如,求5的阶乘,结果输出如下:
[code]f(5)=5 * f(4) f(4)=4 * f(3) f(3)=3 * f(2) f(2)=2 * f(1) f(1)=1 * f(0) 拆解问题完毕,开始分而治之 f(1)=1 f(2)=2 f(3)=6 f(4)=24 f(5)=120
从上面的步骤我们可以清晰的看到递归算法的第一步是分治,把复杂的大的问题,给拆分成一个一个小问题,直到不能再拆解,通过退出条件retrun,然后再从最小的问题开始解决,只到所有的子问题解决完毕,那么最终的大问题就迎刃而解。上面的打印信息,符合栈数据结构的定义,先进后出,通过把所有的子问题压栈之后,然后再一个个出栈,从最简单的步骤计算,最终解决大问题,非常形象。
代码实现(方法二---引用大佬的)
[code] public static int sum = 0; public static int count = 0; public static void main(String [] args) { f(0); System.out.println(count); } public static void f(int n) { // sum是取牌的数量,n是取得牌的数字是几。这里n的范围是0到12. if(sum>13 || n>13) return ; //sum>13表示牌取多了。n>13表示一共13种牌,不可能取到第14种。 if(sum==13 ) { //只有当取牌的数量达到13张的时候,表示这次可行。 count++; return; } for(int i=0; i<=4; i++) { //从0到4,一共5种取法,因为有的牌可以一张不取。 sum += i; f(n+1); sum -= i; //回溯回去,比如上次取了一张,先减去那一张,这次可以取两张。 } }
小剧场:才自清明志自高!
看-清 原创文章 27获赞 1访问量 840 关注 私信相关文章推荐
- mysql-通过例子解释四种隔离级别
- linux 文件操作函数 通过例子来解释 父子间文件描述符共享 内存映像图
- java中通过ndk调用c/c++ 例子,详细解释
- 通过一个例子来解释startService和bindService的区别
- linux 文件操作函数 通过例子来解释 父子间文件描述符共享 内存映像图
- 关于寒江独钓中tdifw_smpl例子不能通过编译的解释
- 通过例子分析Cocos2d-x的Resolution
- 把一个字符串通过递归转换成相应数字
- 递归算法及经典递归例子代码实现
- 补码复习的好例子---Int范围的科学解释
- 【转载】绝对干货!Linux小白最佳实践:《超容易的Linux系统管理入门书》(连载九)如何通过源代码安装软件
- 斐波那契非递归解法
- 通过递归的方式实现深度clone
- 通过例子看struts2原理
- 通过反编译一个简单的C程序,解释堆栈的变化
- Mysql——通过例子理解事务的4种隔离级别
- javascript:模拟类私有属性,通过类方法调用例子
- 通过一个实际的例子学习SQLServer存储过程
- 时滞微分方程的matlab解法之二dde23---另外一些例子
- Java青蛙跳台阶的递归和非递归解法