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