球盒问题之二:n分解成m正数和解题代码
来源:互联网 发布:提字器软件 编辑:程序博客网 时间:2024/06/12 01:34
球盒问题之二:n分解成m正数和解题代码
在上一篇博文 球盒问题之一:方案概览 中给出了S(n,m)的代码实现方案。
而对于前2种情况的解决方案并未给出代码与问题解决的思路。在这里,就将第一种与第二种情况下的解决问题的思路与代码分享。
思路:
第一种情况,n球同,m盒同,不空。记解为D(n,m)。
第二种情况,n球同,m盒同,可空,记解为H(n,m)。
那第一种情况与第二种情况有什么关系呢。先看第一种情况,因为所有盒子都不空,那所有盒子至少放一个球。那要是先将每个盒子都先放一个球呢,还剩下n-m个球要放到m个盒子中。而此时m个盒子中已经有一个球了,所以问题就退化成了将n-m个球放到m个盒子中,可以有空盒子这种情况下的解。
即 D(n,m)=H(n-m,m)。
而从上一篇博客我们已经知道了H(n,m)是D(n,1)加上D(n,2)。。。一直加到D(n,m)。
聪明如你,一定会想到,如果用数学来解决这个问题,那这就可以组成一个二元方程组。
而当用计算机解决这类方程式相关的问题时,就可以用动态规划相关的思路了。说白了就是递归调用直到将问题递归转化成最简单情况下的子集,然后求解。
解题代码如下:
class SplitNumToHeap{public: SplitNumToHeap():runTimes_(0){}; virtual ~SplitNumToHeap(){}; //盒不可空 int splitNotEmpty(int ball,int box){ if(ball == box || 1 == box) return 1; else if(ball<box) return 0; runTimes_++; return splitCanEmpty(ball-box,box); }; //盒可空 int splitCanEmpty(int ball,int box){ if(1==box || 1==ball) return 1; return sumFunctionNotEmpty(ball,box); }; //球数不变,盒数从1到最大值,计算盒不空所有放法之和。 int sumFunctionNotEmpty(int ball,int boxMax){ int result =0; for(int i=1;i<=boxMax;i++) { result+=splitNotEmpty(ball,i); runTimes_++; } return result; }; //运行次数统计 int getRunTimes(){return runTimes_;}; void clear(){runTimes_=0;};private: int runTimes_;};
用盒不可空(n分解为m个数之和)做了几次测试,数据如下:
ball 100 put in box 99 can 1 runTimes 1ball 100 put in box 50 can 204226 runTimes 543737ball 100 put in box 25 can 7037286 runTimes 18973294ball 100 put in box 10 can 2977866 runTimes 8313067ball 100 put in box 2 can 50 runTimes 147ball 10 put in box 4 can 9 runTimes 21ball 10 put in box 5 can 7 runTimes 15ball 8 put in box 5 can 3 runTimes 7ball 8 put in box 3 can 5 runTimes 12ball 8 put in box 4 can 5 runTimes 9ball 8 put in box 6 can 2 runTimes 7ball 9 put in box 6 can 3 runTimes 8ball 11 put in box 6 can 7 runTimes 16ball 5 put in box 6 can 0 runTimes 0ball 5 put in box 3 can 2 runTimes 4ball 15 put in box 3 can 19 runTimes 48ball 15 put in box 8 can 15 runTimes 37
用几个参数核对了下,能对上。比如8分3个数和是和,10分2个数和是5等。
测试与打印代码基于Qt5.3,如下:
void MainWindow::on_BtnBallBox_clicked(){ SplitNumToHeap split; int ball=ui->lineEditBall->text().toInt(); int box=ui->lineEditBox->text().toInt(); int solutions=split.splitNotEmpty(ball,box); ui->lineEditSolutions->setText(QString::number(solutions)); ui->lineEditRunTimes->setText(QString::number(split.getRunTimes())); std::cout<<"ball "<<ball<<" put in box "<<box<<" can "<<solutions<<" runTimes "<<split.getRunTimes()<<std::endl; split.clear();}
0 0
- 球盒问题之二:n分解成m正数和解题代码
- 球盒问题之三:n分解成m个正数和所有组合
- 解题报告 之 SOJ2666 分解 n!
- 008华为机试分解字符串,M,N问题
- 编程珠玑: 12章 取样问题 12.1程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复-------解题总结
- 编程珠玑: 12章 取样问题 12.1程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 优化解法-------解题总结
- 编程珠玑: 12章 取样问题 12.3设计空间,程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 -------解题总结
- 编程珠玑: 12章 取样问题 12.3设计空间,程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 解法2-------解题总结
- SVD(奇异值分解)算法_计算任意N*M矩阵_C语言代码
- 矩阵快速幂--(1+sqrt(2)) ^n 分解成 sqrt(m) +sqrt(m-1)
- GOP之M和N值介绍
- C语言正数和负数循环右移,左移,把某正数的第m位(从0开始)到n位取反
- N个正数选取若干个数之和最接近M
- 算法学习笔记之二:从1到n的正数中1出现的次数
- n后问题之二
- 贪心算法,n分解成自然数只和,求最大成绩问题
- sql语句,关于limit m,n;和 limit m offset n;的问题
- 2017.11.3 N盘M柱汉诺塔问题通解 DP 解题报告
- 并查集
- Filter学习
- iOS开发UI篇—程序启动原理和UIApplication
- 弯下腰,拾起你无价的尊严
- 洛谷 P1133 教主的花园
- 球盒问题之二:n分解成m正数和解题代码
- OAuth 2和JWT - 如何设计安全的API?
- 位图与哈希扩展:Bloom Filter(布隆过滤器)
- Cookie用法
- Freeline的快速集成
- Intent(显示使用intent)
- 数据结构二叉树之通过前序和中序恢复二叉树后续方法输出
- hadoop-2.7.3的nodemanager自动关闭问题
- 卷积神经网络大总结