【Note】动态规划初步1-Ch9-《算法竞赛入门经典2nd》

来源:互联网 发布:ip怎么看域名 编辑:程序博客网 时间:2024/04/28 13:33

第一个博客的第一篇文章,献给算法。

最近在学习《数据结构与算法设计》这门课,老师讲的很快,笔者之前从未设计过信息学竞赛之类的东西,又深知DP问题的博大精深,希望通过读书来获得一些新的知识与技能,博文不仅可以传递知识,让读者们指出我的错误,又可以当作自己复习的资料,是很好的选择。我喜欢这种分享的精神。

所以,开始了!

9.1   数字三角形

定义状态d(i, j)为从格子(I, j)出发时能得到的最大和(包括格子本身的值)。原问题的解转换为求解d(1,1)。我们得到了状态转移方程:d(I,j) = a(I, j) + max{ d(i+1, j) , d(i+1, j+1) }

注:i为行数,j为此行的列数。

动规问题的核心是状态和状态转移方程。

9.1.2介绍了三种处理方法,第一个是递归计算,由于大量的重复计算显然不好;第二个是递推计算,是一个还不错的选择;第三个是记忆化搜索,其实就是融合了第一种方法,将已经算过的值额外保存下来。具体地,我们将每个值赋为-1,因为-1这个数字永远不可能“通过计算得到”,所以相当于一个安全的信号。

9.2 DAG上的DP

9.2.1 DAG模型

嵌套矩形问题:二元关系,用图论知识建模,有向图,无环。我们希望求得这个图中最长的路径。此外,题目还要求矩形编号的字典序尽量小。

d(i)表示从i出发的最长路长度,状态转移方程:d(i)= max{ d(j)+1 | (i, j)属于Edge集合}

int dp(int i)方法为记忆化搜索程序,有些令人困惑的是如果要跑完整个程序,应该另i的值为多少呢?打个比方,现在的二元关系的整除关系,有{2,3, 4 ,6, 12, 40, 61},那么我们可以发现,23两个数字之前不存在二元关系,34之间亦然,那么如果取i=2,另一条支路3就没有被遍历到。不过像61这样的独立子图,不需要遍历。

还有一个让我想了一会的话是,“只把break语句删除是不够的”。其实仔细想想也很简单,打印出来的只是一颗树通过DFS搜索,而并不是完整的一条条routine

 

硬币问题:

状态:“还需要凑够的面值”,初始状态是S,目标状态为0。求硬币数目的minmax。定义V(也就是value)为硬币面值,如价值五元的硬币有V(j)=5。现在的状态为i,使用了j,转移到i-Vj

d(i)定义为从i出发到节点0的最长路径长度。代码如下。Python3.4.


字典序这样的细节可能还要推敲一下。


接下来我会实践部分的例题和习题,数了一下如果都完成有50+的题目量呢。但愿在学期结束之前能写完大部分想写的。


0 0