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