第三章作业与学习总结
引论:动态规划思想与分治法思想有点类似,都是将原本的大问题划分成一系列的小问题,但其实两者的区别还是相当大的。本文重点分享我对动态规划思想的理解与运用。
一、对动态规划算法的理解
首先,动态规划算法非常适合解决求最优解的问题,通过动态规划的思想,我们能够将一个问题的最优解推至其子问题的最优解,就像商人过路问题一样,商人到达终点所需要的过路费取决于他上一步花费的过路费,而他上一步花费的过路费有可以追溯到更早之前的情况。虽然动态规划的思想容易让人接受,但掌握动态规划算法设计的方法才是重中之重——一般分为四步:1.根据实际情况找出最优解的性质。 2.根据最优解性质推导出递归方程(这一步尤为重要)。 3.分析递归方程,设计合适编程语句。 4.通过填表法记录所有最优解情况,并找到题目所需的最优解。
当我们使用动态规划算法的时候,不要因为省事而节省了写出递归方程式的步骤,往往正是这一步能够帮助我们更好地理解问题,分析解题策略。而动态规划又常常到重叠子问题,因此我们常用填表法的方法,来存放每一种情况的最优解,最后得出总问题的最优解。
个人认为,利用动态规划算法解决问题要着手于解决三个“怎么样”:第一,怎么样得出当前问题的最优子结构? 第二,怎样通过最优子结构写出递归方程式? 第三, 怎样通过递归方程式来编程以完成填表?
二、列出编程题的递归方程式
第一题: 求最长的递增子序列
根据题意可知,以1 3 5 2 9为例子, 9的最长递增序列取决于前面四个数字的最长递增子序列加上自己。
用m[ i ]表示以ai为结尾的最长递增子序列,则m[ i ] = max { m [ k ] + 1 | a [ k ] <= a [ j ] } ( i <= k < j)。
第二题: 租游艇
根据题意可知, 1 —— n租船点的最少费用取决于1 到 k点的费用,再加上 k到n点的最少费用。
用cost[ i ][ j ]为从i 站到 j 站的最小费用, m[ i ] 表示i点的最优解
m [ i ] = min { cost[ i ] [ k ] + m [ k ] } ( i < k <= n)
三、结对编程情况汇报
由于第三章学习到的动态规划无论从思想上还是算法实现上都远比分治法难,所以在学习本章的时候,我们更注重了结对编程。 首先, 我与编程搭档共同思考了如何有效的将题目的要求转化为动态规划思想,再将思想实现为算法,
同时,因为练习题的难度都比较大,所以我们决定一起解题。在解题过程中,我们虽然不能完全写出递推方程式,但我们尝试通过编程找出递推规律,并一起完成了最后一题。对我来说,通过结对编程,我既能和同伴巩固知识,又能分享经验,共同解决难题。
(期中考试过去了,事实让我明白,即使自己认为学习得很不错,但上机测试将我打回原形,证明我的学习还不够深入,还没完全透彻的理解其中的知识。)