典型的递归求解,要查找最大值,如果用暴力基本解决不了,而且特别浪费时间。这里用递归,但是用递归有个问题三角形行数大于1小于等于100通常意义的递归模版在这里由于递归太深会导致栈溢出,所以考虑对递归进行优化。
递归中很多计算都是重复进行的,本质就是把一个问题分解成若干个小问题,若干个小问题可能又互相重叠,就存在重复计算,就导致效率低下。所以这里对递归进行优化的措施主要就是把重复计算的次数尽量降低。看代码。设置一个cs[101][101]的数组,初始化为无限大,把每次递归的值存放在里面,若涉及到重复计算,由于cs数组里面有值的存在,所以就返回上一层这一次不进行递归的操作(别忘了递归是在栈中进行各项操作的,栈的先进后出后进先出的性质就用上了)。
递归操作,max(mmax(c+1,d),mmax(c+1,d+1)是这个程序的关键。怎样理解?我觉得简单点的理解就是:题中限制了两种路径走法,不是向下就是向右,所以递归操作,每一次判断向下走和向右走的大小。走到终点处,回溯,遍历每种情况。(这个时候把递归想象成一棵树,这里解释的可能有点问题)。
include<stdio.h>
#include<math.h>
int s[101][101];
int cs[101][101];
int n;
int max(int a,int b)
{
return a > b ? a : b;
}
int mmax(int c,int d)
{
if(cs[c][d]!=0xffffffff) return cs[c][d];
if(c==n-1) return s[c][d];
cs[c][d]=s[c][d]+max(mmax(c+1,d),mmax(c+1,d+1));
return cs[c][d];
}
int main(void)
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
{
scanf("%d",&s[i][j]);
cs[i][j]=0xffffffff;
}
}
printf("%d\n",mmax(0,0));
return 0;
}