题目描述
【问题描述】
给定一个数塔,如下图所示。在此数塔中,从顶部出发,在每一节点可以选择走左下或右下,一直走到底层。请找出一条路径,使路径上的数值和最大。
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;
}
如果对各位看官有帮助不妨留下一个点赞 ̄ω ̄=。