在刚刚学习编程时候,有时候会遇到一些动态规划问题,动态规划就是情况很多,需要有动态的思想来考虑问题,需要动态考虑,一般是用递归来解决
今天我们是来讨论一道数塔问题。
问题是这样的:
给定一个数塔,如下图所示。在此数塔中,从顶部出发,在每一节点可以选择走左下或右下,一直走到底层。请找出一条路径,使路径上的数值和最大。
9 |
12 | 15 | |||||||
10 | 6 | 8 | ||||||
2 | 18 | 9 | 5 | |||||
19 | 7 | 10 | 4 | 16 |
首先要认识什么是递归,递归就是不断调用自身来求多种可能的解,也可以抽象的认为,递归就是把所有的路都走了一遍,走了一遍以后再来求取最优解,每一个递归都要有一个可以跳出递归的条件(这个是必须的,不然就会无限下去)所以递归也是一种比较累的方法,对于计算机来说。那么来介绍一下此题的递归思路。这道题用递归来解决,思路如下:
任意选一个数,它的下面有两个数,其中一条是值大的,另一条是值较小的,我们要选择那一条较大的,除非任意选的·数已经是最后一排。这个就是思路,比较简单,下面是代码的实现,递归最重要的是那个递归结构,即递归函数:
int numberoftank(int number,int **tank,int line,int lie,int mine){
if(line==number-1) return mine;//返回条件,当前行数到达最底层
else{
if(numberoftank(number,tank,line+1,lie,tank[line+1][lie])>=numberoftank(number,tank,line+1,lie+1,tank[line+1][lie+1]))//比较下面两个数的值大小,由此判断返回值
{
return numberoftank(number,tank,line+1,lie,tank[line+1][lie])+mine;
}
else
{
return numberoftank(number,tank,line+1,lie+1,tank[line+1][lie+1])+mine;
}
}
}
此处的numbe为总层数,**tank为储存数塔的动态二维数组,line为当前行数,mine为当前的数值,此处加上mine是简化代码,免得最后还要判断第一个,直接从第一个开始算起。
若此处还要输出,最大组相应的数,则代码需要如下改进(办法比较笨,有好的方法可以提出来,一起讨论):
int k=0;
for(int i=1;i<n;i++)
{
if(numberoftank(n,tank,i,k,tank[i][k])>=numberoftank(n,tank,i,k+1,tank[i][k+1])){
result[i]=tank[i][k];
}
else
{
result[i]=tank[i][k+1];
k+=1;
}
}
是在mian函数中间添加这串代码,result是用来储存每一行的相应最大数列的值,k为列数:
此处代码的意思就是,从第二行开始找起,比较两个数的相应数塔谁大,谁大就把他放进结果数组里面;然后换下一行,是上一列对应的下面两个。
今天就先写到这里,以后想到什么新的再来补充吧!