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

 

 

2.问题描述:第一行输入n为三角形的行数。后n行依次输入数据。从三角形上顶点开始,每次对其下方两个数据进行选择,使得每次选择使所有所选值之和最大。该问题是一个动态规划问题,需要实时进行判断才能最终得出结果。

3.算法描述:

 1 #include<iostream> 
 2 #include<cmath>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int i , j ;
 8     int n;
 9     cin>>n; 
10     int a[n+1][n+1];
11     int sum[n+1][n+1]; 
12     for(i = 1;i <= n;i++)//输入 
13     {
14         for(j = 1;j <= i;j++)
15         {
16             cin >> a[i][j];
17         }
18     }
19     
20     for(j = 1; j <= n;j++)//将a数组最后一行的数据同步到sum数组的最后一行。 
21     {
22         sum[n][j] = a[n][j];
23      } 
24      
25     for(i = n - 1;i >= 1;i--)//从最后一排向上倒算,寻找最大值 
26     {
27         for(j = 1;j <= i;j++)
28         {
29             sum[i][j] = max(sum[i+1][j],sum[i+1][j+1]) + a[i][j]; 
30         }
31     }
32     
33     cout << sum[1][1];
34     return 0;
35 }

首先,用一个二维数组存放数字三角形,每行元素个数与行数相同。

接着再定义一个二维数组,用来存放叠加后的各个数据。

将数字三角形最后一行的数据同步至另一二维数组的最后一行,随后进行循环运算,从数字三角形倒数第二行开始,每个数据选择下方两数据中最大值进行相加,相加的结果存放于另一数组的与该元素相同的位置。一直到第二行皆如此操作。

最后所得第一行的唯一一个元素即为最大值。

4.时间复杂度:O(n)

5.心得体会:对于一些动态规划问题,可以使用递归的方法进行解决,当然,也可以尝试使用循环的问题进行解决,将每一个子问题解决后即可得到和问题的解。