算法第三章上机实践报告

1.实践题目

数字三角形

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

 

2.问题描述

本题要求:1)输入数组(双重循环,二维数组);2)找出最大路径。最大路径要求通过动态规划法来求取。

3.算法描述

先用递归的方法找到大致思路,然后将大问题差分成小问题,画表格找到动态规划法的窍门。

1)递归思路:

用二维数组 d[ l ][ r ] 存数字三角形
 if ( l  ==  n) maxSum( l , r ) = d [ l ][ r ] ;
 else maxSum ( l , r ) = max { maxSum( l+1, r ) , maxSum( l+1, r+1 ) }

/*递归方法中的递归函数*/

int MaxSum(int l,int r) //a[l][r]为输入的数字三角形

{
    if(l==n) //n为数字三角形的层数
        return a[l][r];
    else
        return max(MaxSum(l+1,r),MaxSum(l+1,r+1))+a[l][r];
}

2)有递归算法可以看到,递归思想是把求最大路径时左和右的不同分成小的问题,代入动态规划法中,既然想知道最大的路径是什么,那么最大路径中的子路径也是最大的,由此可推,在数字三角形的第二行(所有路径第一行都是同一个数)哪边最大,哪边就是最大路径的第一个方向。然后,那一边的左右两个数字哪个最大哪个就是下一个数。因此,自底向上,下层的点就是选择上层与其相连点的最大路径。因此从下往上遍历元素,提取大的那一项,绘制表格如下(横排为j,竖排为i):

 

1 2 …… n-1 n
2        
……   a[i][j]    
n-1   a[i+1][j] a[i+1][j+1]  
n        

 

设最长路径长度为m[i][j],m[i][j]等于本身的值加上上面一行和自己相邻两数的最大值。相关代码如下:

for(int j = 1; j <= n; j++)
        m[n][j] = a[n][j];
    for(int i = n - 1; i >= 1; i--) {
        for(int j = 1; j <= i; j++) {
            m[i][j] = a[i][j] + max(m[i + 1][j], m[i + 1][j + 1]);
        }
    }
    cout << m[1][1] << endl;

 

全部代码如下:

#include<iostream>
using namespace std;
int a[105][105];
int m[105][105];
int max(int a, int b) {
    if(a > b) return a;
    else return b;
}
int main() {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= i; j++) {
            cin >> a[i][j]; 
        }
    }
    int sum = 0;
    for(int j = 1; j <= n; j++)
        m[n][j] = a[n][j];
    for(int i = n - 1; i >= 1; i--) {
        for(int j = 1; j <= i; j++) {
            m[i][j] = a[i][j] + max(m[i + 1][j], m[i + 1][j + 1]);
        }
    }
    cout << m[1][1] << endl;
    return 0;
} 

 

4.算法时间及空间复杂度分析

因为在动态规划中存在双重循环,所以上面的算法的时间复杂度是O(n2),空间复杂度同原始的数组一样大小。

5.心得体会

我对于动态规划法还不是十分熟练,还有很长一段把路要走,虽然在结对编程中做出了两道题,但是我个人对此并不很了解,所以还是要再多看书多看例题。

posted @ 2019-10-20 05:03  Backey  阅读(147)  评论(0编辑  收藏  举报