动态规划&递归-危险的组合
1. 问题描述 有若干个铅盒和铀盒(足量),要求将n(n<=30)个盒子进行排列组合,输出满足至少有三个铀盒相邻的排法的个数。例如输入5,要求输出8。
2. 问题分析
说明: 柚盒用1表示,铅盒用0表示,下同。首先,考虑在n-1个盒子已经符合排列要求的情况下,当第n个盒子为1还是为0时,满足条件的排列数. 其情况描述图如图(1)。
对于图(1):当n-1个时满足要求时,如果增加一个盒子n,那么无论n为1还是0,新的排列均满足。故有:其次,考虑在n-1个盒子不符合排列要求的情况下,当第n个盒子为1还是为0时,满足条件的排列数. 其情况描述图如图(2)。2*f(n-1)
个。
【动态规划&递归-危险的组合】对于图(2):最后,由于不存在其它情况,且上两种情况无重叠,所以:
① 首先推测第n个位置不能为0. 采用假设法。当n-1不成立时,如果n盒子为0,那么新的n个盒子的排列仍不成立,所以,第n个盒子不能为0.
② 其次推测第n个位置只能为1. n-1个盒子的排列中没有一个满足至少有三个铀盒相邻,说明,n-1个盒子的排列中,最多只能有两个1挨着,剩下的1和0轮流交替,所以,要使n-1个盒子不成立,而n个盒子的排列成立,则第n个盒子只能为1.
③ 再次,推测n-3至n-1的排列。②中提到n-1个盒子的排列中,最多只能有两个1挨着,那么如果有两个1挨着的话,这两个1的位置可以在任意位置,可以在第1和第2位,也可以在第n-2和第n-1位。为了满足成立条件,在第n个盒子能为1的情况下,且要使n个盒子的排列符合条件,那么第n-1和第n-2位上只能为1,由于n-1的排列中,最多只能有两个1相邻,所以n-3位只能为0. 由此推测出图(2)中的情况。
因此,图(2)中表示,n-1个盒子时不成立,摆放情况为110···,而n个盒子时能成立的盒子摆放示意图。因此,其成立个数应为n-4个盒子时不成立的个数。而对于n-4个盒子的摆放总数为pow(2,n-4),成立的总数为f(n-4),故图(2)成立的总数为:pow(2,n-4)-f(n-4)
.
f(n)=2*f(n-1)+pow(n,n-4)-f(n-4)
,其中n由分析过程可知必须大于等于4。而对于0,1,2,3则分别为初值:0,0,0,1.3. 代码实现 递归函数实现:
int calcu(int n)
{
if (n<3)
return 0;
else if (n==3)
return 1;
else
return 2*calcu(n-1)+ ( (int)pow(2.0, n-4)-calcu(n-4));
}
4. 感悟 感悟:平时的动态规划都是在探讨边界条件,求出状态转移方程,而且一般的求法是正向求解,重点关注第n位(下一位)的增量情况。而本题另辟蹊径,使用了逆向求解,在n-1不成立时,逆向求解n-1的排列方式,这是平时思维中的一点盲点。
Reference: http://tieba.baidu.com/p/2347438416
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 宋仲基&宋慧乔(我们不公布恋情,我们直接结婚。)
- 21天|21天|M&M《见识》04
- 二叉树路径节点关键值和等于目标值(LeetCode--112&LeetCode--113)
- 2021—3—8日教练实践总结&呼吸练习&觉察日记
- 奇迹-妖妈|奇迹-妖妈 感恩日记46/365&非暴力沟通第3天
- 前端|web前端dya07--ES6高级语法的转化&render&vue与webpack&export
- 数据技术|一文了解Gauss数据库(开发历程、OLTP&OLAP特点、行式&列式存储,及与Oracle和AWS对比)
- Python|Win10下 Python开发环境搭建(PyCharm + Anaconda) && 环境变量配置 && 常用工具安装配置
- gem|gem & pod 记录