1.实践题目
7-1 数字三角形 (30 分)
给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。
输入格式:
输入有n+1行:
第 1 行是数字三角形的行数 n,1<=n<=100。
接下来 n行是数字三角形各行中的数字。所有数字在0..99 之间。
输出格式:
输出最大路径的值。
2.问题描述
输入一个n行的三角形,每行的数字个数为该行的行数,设计一个算法使得三角形自顶向下的路径中数字的和最大。
3.算法描述
因为要求最大和路径,可以反推,用自底向上的方法来求。创建一个新的数组b[],把输入数组a[]的最后一行赋给b,利用递推公式b[i][j]=a[i][j]+max{b[i+1][j],b[i+1][j+1]},最后返回b[1][1]即可。
#源代码:
#include <iostream> using namespace std; int a[150][150]; int b[150][150]; int main() { int n; cin>>n; int i, j; //输入数组 for(i =1;i <= n;i++){ for(j = 1;j <=i;j++){ cin>>a[i][j]; } } //把a的最后一行赋值给b的最后一行 for(i =1;i <= n;i++){ b[n][i] = a[n][i]; } //自底向上 for(i = n;i > 1;i--){ for(j = 1; j<= i;j++){ if(b[i][j] > b[i][j+1]){ b[i-1][j] = a[i-1][j] + b[i][j]; }else { b[i-1][j] = a[i-1][j] + b[i][j+1]; } } } cout<<b[1][1]; return 0; }
4.算法时间及空间复杂度分析
因为采用了双重循环,时间复杂度为O(n^2),同时采用二维数组,空间复杂度也为O(n^2)。
5.心得体会
这道题难度不是很大,运用了动态规划的思想以及递归的方法, 将原问题分成若干子问题进行解决。我和我的队友通过讨论得出了该问题的递推公式,大大增快了做题效率。