算法第三章上机实践报告

一、实践题目

这一次由于我只做出了第一道实践题,即数字三角形问题,所以没的选择,只能写这道题的实践报告了。

二、问题描述

 题目里虽然没有说,但是老师要求使用第三章的动态规划算法,同时还要用上“备忘录”,不然的话提交会出现运行超时的错误。

三、算法描述

程序的大致思路就是通过一层层的递归,要求n行数字三角形的最大路径和,就要先求出(n-1)行数字三角形的最大路径和,依次类推。

其递归方程为:源代码为:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int sum(int i, int j, int n, int a[100][100], int num[100][100])
 5 {
 6     if (num[i][j] != -1)
 7         return num[i][j];
 8     //若该位置的值不为-1,则说明已经保存有数据,直接返回结果,节省计算的时间
 9     if (i == n - 1)
10         num[i][j] = a[i][j];
11     //已经递归到最深一层,直接把数字三角形对应的值存入备忘录
12     else
13     {
14         int x = sum(i + 1, j, n, a, num);//求其左下方的最优子结构
15         int y = sum(i + 1, j + 1, n, a, num);//求其右下方的最优子结构
16         num[i][j] = (x >= y ? x : y) + a[i][j];
17         //比较x、y的值,将最优解存入备忘录
18     }
19     return    num[i][j];
20 }
21 
22 int main()
23 {
24     int a[100][100];//定义一个二维数组存放数字三角形
25     int n;
26     cin >> n;
27     for (int i = 0;i < n;i++)
28         for (int j = 0;j < i + 1;j++)
29             cin >> a[i][j];
30     int num[100][100];//定义一个备忘录存放最优子结构
31     for (int i = 0;i < n;i++)
32         for (int j = 0;j < i + 1;j++)
33             num[i][j] = -1;//对备忘录进行初始化
34     int value = sum(0, 0, n, a, num);
35     cout << value;
36     system("pause");
37     return 0;
38 }

 四、算法时间及空间复杂度的分析

时间复杂度:

T(n)= n + (n-1) + (n-2) + … + 1 = n(n-1)/2 = n^2

在第n行,程执行n次将数据存入备忘录,(n-1)层每个数字经过一次比较,最后执行(n-1)次将数据存入备忘录,依次类推,得出最后时间复杂度为n^2。

空间复杂度:

程序需要用到的空间,是一个备忘录数组,数组大小为n * n,即空间复杂度O(n)= n^2。

五、心得体会

由于对动态规划算法的不熟悉,所以在这道题上花费了太多时间,以至于没有时间去做其他题。此外,备忘录方法真的可以很大程度上节省程序运行所需的时间,我一开始打的代码因为没有用备忘录,提交上去后就直接超时了。

孰能生巧,这类新算法、新思想还是要多打代码才能够熟练使用啊。

posted @ 2019-10-21 20:29  月Raido  阅读(127)  评论(0编辑  收藏  举报