数字三角形的多种解法思路

2 篇文章 0 订阅

如图所示的数字三角形,从顶部出发,在每一结点可以选择向左走或得向右走,一直走到底层,要求找出一条路径,使路径上的值最大。
在这里插入图片描述

输入描述 Input Description

第一行是数塔层数N(1<=N<=100)。

第二行起,按数塔图形,有一个或多个的整数,表示该层节点的值,共有N行。
输出描述 Output Description

输出最大值。
样例输入 Sample Input

5

13

11 8

12 7 26

6 14 15 8

12 7 13 24 11
样例输出 Sample Output

86

思路1:普通递归 用二维数组存放三角形。
a[r][j]:第r行第j列的数字
sum(r,j) :从a[r][j]到底边的各个路径中最大数字之和。 复杂度是O(2^N)

#include<iostream>
#include<algorithm>
#define MAXM 110
int a[MAXM][MAXM];
int n;
using namespace std;
int sum(int i, int j)
{
	if(i == n)  
	   return a[i][j];
	int x = sum(i+1,j);
	int y = sum(i+1,j+1);
	return max(x,y) + a[i][j];
	
} 
int main()
{
	cin >> n;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			cin >> a[i][j];
		}
	}
	cout << sum(1,1);
}

此方法重复计算的太多导致时间超时
优化, 进行记忆性递归 定义一个二维数组 记录每个坐标到下面的最大值。将该数组全部赋值为0,每一项计算前加一个判断 如果不为0,则直接跳过计算防止时间的重复 时间复杂度O(n*n)

#include<iostream>
#include<algorithm>
#define MAXM 110
int sum[MAXM][MAXM] = {0};
int a[MAXM][MAXM];
int n;
using namespace std;
int Sum(int i, int j)
{
	if(sum[i][j] != 0)  return sum[i][j];
	if(i == n)  sum[i][j] = a[i][j];
	else{
	int x = Sum(i+1,j);
	int y = Sum(i+1,j+1);
	sum[i][j] =  max(x,y) + a[i][j];
   }
   return sum[i][j];
} 
int main()
{
	cin >> n;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			cin >> a[i][j];
		}
	}
	cout << Sum(1,1);
}

优化 递归变递推 从最下面一行开始逐一往上进行计算

#include<iostream>
#include<algorithm>
using namespace std;
#define MAXM 110
int main()
{
	int a[MAXM][MAXM];
	int n, i, j;
	cin >> n;
	for(i = 1; i <= n; i++)
	   for(j = 1 ; j <=i; j++){
	   	   cin >> a[i][j];
	   }
	for(i = n-1; i > 0; i--){
		for(j = 1; j <= i; j++){
			a[i][j] = max(a[i+1][j], a[i+1][j+1]) + a[i][j];
		}
	}
	cout << a[1][1];
	return 0; 
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值