递归结构中的动态规划

版权声明:个人笔记,仅供复习 https://blog.csdn.net/weixin_42373330/article/details/82822052

表达式上的动态规划
最优矩阵链乘

给出n个矩阵组成的序列,设计一种方法把它们依次乘起来,使得总的运算量尽量小。假设第i个矩阵Ai 是Pi-1 X Pi的。

  • 用状态f(i,j)表示i到j矩阵间的运算量,状态转移方程:
f(i, j) = min { f(i, k) + f(k+1, j) + P(i-1)P(k)P(j) }, i <= k < j 

凸边多边形上的动态规划
最优三角剖分

对于一个n个顶点的凸边多边形,有很多种方法可以对它进行三角剖分,即用n-3条互不相交的对角线把凸边多边形分成n-2个三角形。为每个三角形规定一个权函数f(i,j,k) (如三角形的周长或三个顶点的权和),求让所有三角形权和最大的方案

  • 定义f(i,j) 为“从顶点i到顶点j所构成的子多边形的最大三角剖分权和”,则边PiPj在此多边形内一定恰好属于一个三角形
    iPjPk,只要枚举k的位置,就能把多边形分割成两部分。注意到两个多边形的顶点序列仍是连续的,因此有状态转移方程:
    f(i, j) = max { f(i, k) + f(k, j) + w( i, j, k) }

先了解下矩阵链乘:点击这里

最优三角剖分推荐网址:点击这里
树上的动态规划
树的最大独立集

对于一棵n个节点的无根树,选出尽量多的节点,使得任何两个节点均不相邻(称为最大独立集),然后输入n-1条无向边,输出一个最大独立集(如果有多解,则任意输出一组)。

分析:

用d(i)表示以i为根节点的子树的最大独立集大小。此时需要注意的是,本题的数是无根的:没有所谓的“父子”关系,而只有一些无向边。没关系,只要任选一个根r,无根树就变成了有根树,上述的状态定义也就有了意义了。

节点i只有两种决策:选和不选。如果不选i,则问题转化为了求出i的所有儿子的d值再相加;如果选i,则它的儿子全部不能选,问题转化为了求出i的所有孙子的d值之和。换句话说,状态转移方程为:

扫描二维码关注公众号,回复: 3576776 查看本文章

\small d(i)=max\left \{ 1+\sum_{j\in gs(i)}{d(j)},\sum_{j\in s(i)}{d(j)} \right \},其中gs(i)和s(i)分别为i的孙子集合与儿子集合.

代码该如何写呢?上面的方程涉及“枚举节点i的所有儿子和孙子”,颇为不便。其实可以换个角度来看:不从i找s(i)和gs(i)的元素,而从s(i)和gs(i)的元素找i。换句话说,当计算出一个d(i)后,用它去更新i的父亲和祖父节点的类加值\small \sum_{j\in gs(i)}{d(j)}\small \sum_{j\in s(i)}{d(j)}。这样一每个节点甚至不必记录它的儿子的节点有哪些,只需记录父亲节点即可。

 

传统的递推法可以表示成“对于每个状态i,计算f(i)”,或者成为“填表法”。这需要对于每个状态i,找到f(i)依赖的所有状态,在某些时候并不方便。另一种方法是“对于每个状态i,更新f(i)所影响到的状态”,或者称为“刷表法”,有时比填表法方便。但需要注意的是,只有当每个状态所依赖的状态对它的影响相互独立时才能用刷表法。例如,在最优矩阵链乘问题中就无法直接使用刷表法。

猜你喜欢

转载自blog.csdn.net/weixin_42373330/article/details/82822052
今日推荐