算法第三章上机实践报告
Posted 247403wy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法第三章上机实践报告相关的知识,希望对你有一定的参考价值。
1.实践题目
数字三角形
给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。
输入格式:
输入有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]等于本身的值加上上面一行和自己相邻两数的最大值。相关代码如下:
全部代码如下:
#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.心得体会
我对于动态规划法还不是十分熟练,还有很长一段把路要走,虽然在结对编程中做出了两道题,但是我个人对此并不很了解,所以还是要再多看书多看例题。
以上是关于算法第三章上机实践报告的主要内容,如果未能解决你的问题,请参考以下文章