我从事动态编程已有一段时间了。评估动态编程递归的规范方法是创建一个包含所有必要值的表,并将其逐行填充。有关简介,请参见例如Cormen,Leiserson等人:“算法简介”。
我将重点放在二维(逐行填充)的基于表的计算方案上,并研究单元格依存关系的结构,即在计算另一个单元格之前需要完成哪些单元格。我们用表示单元格依赖的单元格的索引集。请注意,必须是无周期的。
我从计算出的实际函数中抽象出来,并专注于其递归结构。形式上,如果递归具有以下形式,则我认为它是动态编程
与,〜Γ d(我)= { (Ĵ,d (Ĵ))| Ĵ ∈ Γ d(我)}和˚F一些(可计算)函数,它不使用ð比通过其他〜Γ d。
当限制的粒度粗糙区域(左侧,左上,上,右上,...当前单元格)的一个观察到有三个基本例(高达对称性和旋转)的有效动态编程递归,通知如何填充表:
红色区域表示(近似)。情况一和二承认子集,情况三是最坏的情况(直到索引转换)。注意,并非严格要求整个红色区域都被Γ覆盖;表格每个红色部分中的一些单元格足以将其涂成红色。明确要求白色区域不包含任何必需的单元格。
第一种情况的示例是编辑距离和最长公共子序列,第二种情况适用于Bellman&Ford和CYK。不太明显的例子包括:对角线而不是行(或列),因为它们可以旋转以适应所提出的情况;有关示例,请参见乔的答案。
不过,对于情况三,我没有(自然的)例子!所以我的问题是:案例三的动态编程递归/问题有哪些示例?