数塔···

题目描述

【问题描述】

给定一个数塔,如下图所示。在此数塔中,从顶部出发,在每一节点可以选择走左下或右下,一直走到底层。请找出一条路径,使路径上的数值和最大。

9

12

15

10

6

8

2

18

9

5

19

7

10

4

16

【输入形式】

输入时第一行一个整数n,表示该数塔的行数,其余n行表示该塔每行的数值

【输出形式】

输出包含两行,第一行为最大路径上的数值之和, 第二行n个数字为从上而下最大路径数值

【样例输入】

5
9
12 15
10 6 8
2 18 9 5
19 7 10 4 16
【样例输出】

59
9 12 10 18 10

思路分析

初步分析该数塔类似二叉树,可采用递归的方式求出所有可能路径的值并记录最大值,在求可能路径的同时记录路径。若想实现递归,就要找到当前元素与它下面两个可达元素序号之间的关系,经过观察找规律,当前元素可达的两个元素的序号为:当前元素序号+当前层数、当前元素序号+当前层数+1。由于在寻找可能路径时不能确定该路径是否为最大路径,所以将每一条路径都储存起来,使用map<int, vector>储存。

代码

#include <bits/stdc++.h>
using namespace std;
int maxm = 0, top = 0, n;
map<int , vector<int>> Path;
int Tier(int x){
	int result = 1;
	for(; x - (result)*(result + 1)/2 > 0; )
		result++;
	return result;
}
void Visit(int start, int last, int* p, int* q, int edge){
	(last > maxm) && (maxm = last);
	if(start > edge){
		if(last == maxm){
			vector<int> tmp(q, q + n);
			Path[maxm] = tmp;
		}		 
		return;
	}
	last += p[start];
	q[top++] = p[start];
	Visit(start + Tier(start), last, p, q, edge);
	Visit(start + Tier(start) + 1, last, p, q, edge);
	top--;	
}
int main(){
	cin >> n;
	int sum = n*(n + 1)/2, a[sum + 1], b[n];
	for(int i = 1; i <= sum; i++)
		cin >> a[i];
	Visit(1, 0, a, b, sum);
	cout << maxm << '\n';
	for(int t = 0; t < n; t++)
		cout << Path[maxm][t] << ' ';
	return 0;
}

如果对各位看官有帮助不妨留下一个点赞 ̄ω ̄=。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值