题目
数塔
【问题描述】
给定一个数塔,如下图所示。在此数塔中,从顶部出发,在每一节点可以选择走左下或右下,一直走到底层。请找出一条路径,使路径上的数值和最大。
【输入形式】
输入时第一行一个整数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
分析
输出路径这一要求就很麻烦
这里代码难以理解的一点是,在从最下面的函数递归的时候,所有路径的sum其实就已经知道了,就可以通过一步步比较sum的大小,把路径储存在c里面去,大致思路就是这样(详解后面更新)
AC代码
#include<bits/stdc++.h>
using namespace std;
int b[1001]= {0};
int c[1001]= {0};
int f(int **a,int n,int x,int y,int sum) {
if(x==n-1)
return sum;
int p=f(a,n,x+1,y,sum+a[x+1][y]);
int q=f(a,n,x+1,y+1,sum+a[x+1][y+1]);
if(p>=q) {
if(b[x]<p) {//b记录最大sum
b[x]=p;
c[x+1]=a[x+1][y];//c记录路径
}
return p;
}
if(b[x]<q) {
c[x+1]=a[x+1][y+1];
b[x]=q;
}
return q;
}
int main() {
int n;
cin>>n;
int **a=new int *[n];
for(int i=0; i<n; i++)
a[i]=new int [n];
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
a[i][j]=0;
for(int i=0; i<n; i++)
for(int j=0; j<=i; j++)
cin>>a[i][j];//完成输入
c[0]=a[0][0];
cout<<f(a,n,0,0,a[0][0])<<'\n';
for(int i=0; i<n-1; i++)
cout<<c[i]<<" ";
cout<<c[n-1]<<'\n';
}