Project Euler 18.给你一组由数字组成的三角形,从三角形的顶端开始,依次移向下一行相邻数字,求从顶端到低端的最大和为多少?

从下面的三角形的顶端开始,向下面一行的相邻数字移动,从顶端到底端的最大总和为23.



也就是 3 + 7 + 4 + 9 = 23.

找出从以下三角形的顶端走到底端的最大总和:

很大程度当我们看到这样问题时,会马上形成一条简单思路,那就是:记录从顶点到最低端的每一条路径,然后算出每条路径的总和,最后综合比较一下就可以得到我们想要的结果。很显然这方法是行得通,但是存在一个弊病,花费的时间很长。所以我们现在需要寻找其他方法来简化路径。

KEY:简化路径。

我们观察最低端的发现,每两个结点会共有一个父结点(我们为了描述方便,我们引进树中父结点这一概念),这样他们的父结点在最后选择孩子的时候,会有两种选择,形成两条路径。题目要求是顶端走到底端的最大总和,所以父结点只接受权值较大的孩子。这样我们通过比较孩子结点来舍弃权值较小的结点,从而简化路径。

算法分析:
  1. 初始化变量:定义一个a[n][n],其中n为三角形的行数
  2. 简化路径:
    • 外层循环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]
    • 循环结束

附加代码:

#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;
}







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值