三爽

导航

第三章

一、
3-2 单调递增最长子序列 (25分)
  我最先想到的方法是方法一:将数组a里的数从小到大排序,得到数组a1,然后找出数组A和A’的最长公共子序列即可如例子中的数组A{5,6, 7, 1, 2, 8},则我们排序该数组得到数组A‘{1, 2, 5, 6, 7, 8},显然这里最长公共子序列为{5, 6, 7, 8},也就是原数组A最长递增子序列。但是这种方法的时间复杂度就超出了题目要求.
  于是我结合了课上讲的方法,想到了设长度为N的数组为{a0,a1, a2, ...an-1),则假定以aj结尾的数组序列的最长递增子序列长度为L(j),则L(j)={ max(L(i))+1, i<j且a[i]<a[j] }。也就是说,我们需要遍历在j之前的所有位置i(从0到j-1),找出满足条件a[i]<a[j]的L(i),求出max(L(i))+1即为L(j)的值。也就是说从前到后开始扫描,将每个元素作为最后一个元素,求此情况下的最长单调递增子序列的长度,并以此作为一个子问题,即每个max[i]为一个子问题。
此时时间复杂度为O(n2)。
由此得出递归方程:
maxs[j] = maxs{max[i] + 1} (0<i<j,0<j<n)
 
二、对动态规划算法的理解
  相比较于之前学习的分治法,动态规划和分治法思想类似,区别在于动态规划的求解的问题经分解以后得到的子问题往往不是互相独立的。
  在用分治法求解时,有些子问题被重复计算了许多次。如果能够保存决的子问题的答案,在需要时再找出已求得的答案,这样可以避免大量的重复计算,从而得到多项式时间算法。为了达到此目的,可以用一个表来记录所有已解决的子问题的答案。管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
基本上动态规划解题思路就是
  1. 明确问题具有最优子结构,并分解问题
  1. 找出递推关系式,注意初始状态即边界条件
  1. 利用循环实现递推关系

我认为最难的地方在于求递推关系式,还有就是初始状态和边界条件,边界条件弄不好很容易陷入死循环(我已经陷入无数次了sad)

求解动态规划问题,通常需要每次都保留所有可能的最优解。但是在全部解决方案列出进行比较之前,无法确定当前局部的最优解就是全部的最优解,因此需要对全部方案记录到数组里面。这里通常用“填表”的方式出现,然而填表的话不一定从上往下或者从左往右,具体还需要注意根据递推方程来决定。

还有一点,学备忘录的时候学到的:为什么不用递推反而不用递归?well,分治法里面递归进行了太多次重复运算。递归解题的时候,假设解第n个问题,需要从n-1,n-2...一直解到第1个问题,再将所有结果相加得到第n个问题的解。而这些步骤显然在解第n-1个问题的时候都做过一遍,增加了许多无用开销。动态规划中,n-1的最优解以及被记录到数组中,或者说备忘录中,就不需要重复计算,大大降低了时间复杂度。

三、结对编程情况

这次算法结对我和队员尝试两个人两台电脑,相比于刚开始的一台电脑两个人一起看,可能交流有减少,但是我感觉可以锻炼到独立性思维回避之前活跃一点,有自己的节奏思考时间,会舒服很多。但是运行编译成功以后还是会交流对方的代码,看看对方是什么思想。还是有帮助的。

 



 

posted on 2020-10-26 23:13  三爽  阅读(85)  评论(0编辑  收藏  举报