从下面的三角形的顶端开始,向下面一行的相邻数字移动,从顶端到底端的最大总和为23.
也就是 3 + 7 + 4 + 9 = 23.
![](http://hi.csdn.net/attachment/201110/3/0_13176527943aAe.gif)
也就是 3 + 7 + 4 + 9 = 23.
找出从以下三角形的顶端走到底端的最大总和:
很大程度当我们看到这样问题时,会马上形成一条简单思路,那就是:记录从顶点到最低端的每一条路径,然后算出每条路径的总和,最后综合比较一下就可以得到我们想要的结果。很显然这方法是行得通,但是存在一个弊病,花费的时间很长。所以我们现在需要寻找其他方法来简化路径。
KEY:简化路径。
我们观察最低端的发现,每两个结点会共有一个父结点(我们为了描述方便,我们引进树中父结点这一概念),这样他们的父结点在最后选择孩子的时候,会有两种选择,形成两条路径。题目要求是顶端走到底端的最大总和,所以父结点只接受权值较大的孩子。这样我们通过比较孩子结点来舍弃权值较小的结点,从而简化路径。
算法分析:- 初始化变量:定义一个a[n][n],其中n为三角形的行数
- 简化路径:
- 外层循环0 <= i < n,初始化i = n-1;
- 内部循环0 <= j< n-1,初始化j=0;
- 如果a[i][j] > a[i][j+1],则a[i-1][j] += a[i][j],否则,a[i-1][j] += a[i][j+1]
- 内部循环0 <= j< n-1,初始化j=0;
- 循环结束
- 外层循环0 <= i < n,初始化i = n-1;
附加代码:
#include <IOSTREAM>
#include <FSTREAM>
#include <TIME.H>
using namespace std;
bool ReadFile(char *filename,int data[][15])
{
ifstream infile(filename);
if (!infile)
return false;
int n=0,m;
for (int i=0;i<15;++i)
{
++n;
for(int j=0;j<n;++j)
{
infile>>m;
data[i][j]=m;
}
}
infile.close();
return true;
}
int main()
{
clock_t s_time,e_time;
s_time=clock();
int data[15][15]={0};
ReadFile("Euler18.txt",data);
int n=15;
for(int i=14;i>=0;i--)
{
n--;
for (int j=0;j<n;j++)
if (data[i][j]>data[i][j+1])
data[i-1][j]+=data[i][j];
else
data[i-1][j]+=data[i][j+1];
}
e_time=clock();
cout<<data[0][0]<<endl;
cout<<"Run Time:"<<(e_time-s_time)/CLOCKS_PER_SEC<<" s"<<endl;
return 0;
}