算法第三章上机实践报告

1.实践题目:数字三角形 

 2.问题描述:

给定一个由 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

3.算法描述
首先,先写出递归方程式:
{
m[i][j] = a[i][j] i=n;
m[i][j] = m[i+1][j] + m[i+1][j+1] + a[i][j];
再运用动态规划的思想,自下而上求值。
}
代码如下:
#include <iostream>
using namespace std;
int Max(int a,int b){
if(a>=b)
return a;
else
return b;
}
int main()
{
int a[100][100],b[100][100],n;
cin >> n;
for(int i = 0;i < n; i ++ ){
for(int j = 0;j <= i;j ++ ){
cin >> a[i][j];
b[i][j] = a[i][j];
            }
        }
for(int i = n-2;i >= 0;i -- ){
for(int j = 0;j <= i;j ++ ){
b[i][j] += Max ( b[i+1][j], b[i+1][j+1] );
         }
        }//自下而上
cout<<b[0][0];
return 0;
}

4.算法时间及空间复杂度分析
时间复杂度:
for(int i = n-2;i >= 0;i -- ){
for(int j = 0;j <= i;j ++ ){
b[i][j] += Max ( b[i+1][j], b[i+1][j+1] );
         }
        }
由该语句可看得出,依次执行了n-1, n -2, n-3.........1 次。(n-1+1) *n/2 = 1/2n^2
所以时间复杂度:O(n) = n^2
 
空间复杂度:
由于没有使用辅助的空间,所以空间复杂度是O(1)
 
5.心得体会
这道题差不多做了一个半小时,一开始以为必须要用递归方法,
结果好不容易做出来也是超时的,也不知道怎么改。其实就是
用备忘录方法和动态规划的思想,自下往上求就是了。由于两
种可能方式都有a[i][j],所以一开始就直接定义一个m数组来
存数值,然后从倒数第二行开始向上求,直接考虑第二种情况
就行了。


posted @ 2019-10-16 21:57  陈明欣  阅读(114)  评论(0编辑  收藏  举报