Description
问题描述:给定一个由n行数字组成的数字三角形,如下图所示。试用动态规划算法,计算出从三角
顶部至底部的一条路径,使得该路径经过的数字总和最大。
注意每个数字只能走向下一行左边或右边的数字,而不能跳跃的走。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输入格式
第一行是数字三角的行数n,1<=n<=100。接下来n行是数字三角各行中的数字,所有数字在0~99之间。
输出格式
输出两行,第一行是计算出的最大路径的和值,第二行是该路径上的数字。若有多条路径,靠右的路径
优先(即仅仅输出靠右的路径即可,无需多条路径都输出)。
如:
Input:
5
7
3 8
8 1 6
2 7 4 4
4 5 2 4 5
有两条路径:7-3-8-7-5和7-8-6-4-5都为30,由于后者靠右,因此仅输出后者。
Output:
30
7 8 6 4 5
输入样例
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例
30
7 3 8 7 5
#include <cstdio>
#include <cmath>
using namespace std;
int maxline2(int **ary, int high, int i, int j, int** map);
int main()
{
int n;
scanf("%d", &n);
int **num = new int*[n];
int **map = new int*[n];
for(int i = 0; i < n; i++)
{
num[i] = new int[i + 1];
map[i] = new int[i + 1];
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < i + 1; j++)
{
scanf("%d", &num[i][j]);
}
}
int max = maxline2(num, n, 0, 0, map);
printf("%d\n", max);
printf("%d ", num[0][0]);
int j = map[0][0];
for(int i = 1; i < n; i++)
{
printf("%d ", num[i][j]);
j = map[i][j];
}
return 0;
}
int maxline2(int **ary, int high, int i, int j, int** map)
{
int **maxl = new int*[high];
for(int i1 = 0; i1 < high; i1++)
{
maxl[i1] = new int[i1 + 1];
}
for(int level = high - 1; level >= i; level--)
{
for(int k = 0; k < level + 1; k++)
{
if(level == high - 1) maxl[level][k] = ary[level][k];
else {
if(maxl[level + 1][k] > maxl[level + 1][k + 1]){
maxl[level][k] = ary[level][k] + maxl[level + 1][k];
map[level][k] = k;
}else {
maxl[level][k] = ary[level][k] + maxl[level + 1][k + 1];
map[level][k] = k + 1;
}
}
}
}
return maxl[i][j];
}