算法第三章上机实践报告

1. 实践报告任选一题进行分析。内容包括:

1.1 问题描述

设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

输入格式:

输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开

输出格式:

最长单调递增子序列的长度

 

1.2 算法描述

需要计算最长子序列,需要以下几个变量:

  • n  表示输入的总序列数
  • arr[i]  表示以arr[i] 为尾元素的序列
  • arr[t]  表示以arr[t] 为头元素的序列
  • max 表示 当前 最长 子序列的长度
  • length[i]  表示 当前 单调递增序序列的长度

用动态规划的思想进行计算,共有以下几个步骤:

  1. 问题分析:该问题要求的是最长子序列,每一个最长子序列都是由短的子序列加一个元素构成,故形成递推关系
  2. 递推关系为:详见1.3.1
  3. 该序列为从始到末开始计算:从左到右填表(数组arr),并计算当前序列的最长子序列lenth[i]
  4. 最优结果:便利数组arr[]得到length[i]的最大值max

 

1.3 问题求解:

1.3.1 根据最优子结构性质,列出递归方程式

当arr[i] > arr[t] && length[i] < length[t] + 1 时:

由arr[i] > arr[t]可知,前大后小(i > t)

由length[i] < length[t] + 1可知, 前一数组当前最长子序列长度小于后一个数组的最长子序列长度

因此,前一数组的最长子序列需要更新+1

由length[i]记录该序列更新后的最长子序列

max记录总遍历过程中的最长子序列,即为所求结果

lenth[i] ={
            length[t] + 1  <-  if(arr[i] > arr[t])
            length[i]  <-  if(arr[i] <= arr[t])
          }

 

1.3.2 给出填表法中表的维度、填表范围和填表顺序。

表一:arr[ ]

表的维度:数组arr[i]为一维数组

填表范围:【0, n - 1】

填表顺序;从左到右

 

表二:length[ ]

表的维度:数组length[i]为一维数组

填表范围:【0, n - 1】

填表顺序;从左到右

 

1.3.3 分析该算法的时间和空间复杂度

时间复杂度:O( n ^2)

解释:该算法使用了两层循环,一层为输入,一层为求结果

 

空间复杂度:O(2n0  + O(1) = O(n)

解释:需要填写两个表( 数组arr[] 和 length[i] ),以及两个变量( max 和 n )

 

1.4 心得体会(对本次实践收获及疑惑进行总结)

实践收获:

学会了如何运用动态规划的方法求解问题,加深了对于动态规划方法的理解,更加熟练地设置判断条件和输入范围,在算法学习上再上一层楼!

 

疑惑:

对于函数如何调用还是不太明白,每次调用函数都会经历报错再修改的过程,目前理解依旧不透彻。

 

2. 你对动态规划算法的理解和体会

1、动态规划的求解过程中需要将大问题分解为小问题,按照一定的方向进行递归运算

2、递归过程中要进行比较,关键是通过比较得出当前的最优解

3、在计算过程中,要精简计算过程,减少重复计算

 

将大问题分解成小问题,这些”小问题“会不会被被重复调用,是运用”动态规划“算法的核心因素

 

posted @ 2021-10-24 20:15  Shannonn  阅读(31)  评论(0编辑  收藏  举报