一、题目
7-1 数字三角形 (30 分)
 

给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。

QQ截图20170929023616.jpg

输入格式:

输入有n+1行:

第 1 行是数字三角形的行数 n,1<=n<=100。

接下来 n行是数字三角形各行中的数字。所有数字在0..99 之间。

输出格式:

输出最大路径的值。

输入样例:

在这里给出一组输入。例如:

5 
7 
3 8 
8 1 0 
2 7 4 4
4 5 2 6 5 

输出样例:

在这里给出相应的输出。例如:

30

二、代码实现

#include<iostream>
using namespace std;

int main(){
int n,a=1;
cin>>n;
int A[101][101];
for(int i = 1;i<=n;i++){
for(int j=1;j<=n;j++){
   A[i][j]=0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=a;j++){
  cin>>A[i][j];
}
a++;   
}
int Max[101][101];
for(int j=1; j<=n; j++){
   Max[n][j]=A[n][j];
}
for(int i=n-1; i>0; i--){
   for(int j=1; j<=i; j++){
       if((Max[i+1][j+1])<Max[i+1][j]){
           Max[i][j] = A[i][j]+Max[i+1][j];
       }
         else Max[i][j] = A[i][j]+Max[i+1][j+1];
   }
}
cout<<Max[1][1];
return 0;
}



三、算法描述
首先根据题意,第一行输入的是这个数学三角的行数,让后通过for循环实现对数学三角的构建。接着定义一个与原数组一样大小的数组用来做备忘录式填表,把数学
三角数组的最后一行填入表中。然后通过比较原数组中最后一行的每两个数,较大的数将与倒数第二行所对应的数相加填入备忘录数组中同样的位置,后面依次填表,
最后的a[1][1]就是我们所求的总和。
四、时间空间复杂度
1.时间复杂度为O(n^2),排序时所用的二重循环,所以时间复杂度为O(n^2)。
2.空间复杂度:在主函数中给变量分配的空间为常数,所以空间复杂度为O(1)。
五、实践心得
这次实践在听课的基础上进一步了解了动态规划问题。一开始对于动态规划是懵懵懂懂的,很模糊,但是经过了这一次上机实践面对一次实际问题的代码的时候会有了
深一步的了解。在这个过程中,我和我的伙伴一起思考,一起找解决方案,最后在实践课下课前完成了这道题的通过。虽然我们只完成了这一题,但还是有收获满满的
满足感。