动态规划-DAG最长路
DAG就是有向无环图,并且在之前已经讨论了如何求解DAG中的最长路,也就是所谓的”关键路径“。但是求解关键路径的做法对初学者来说确实有些复杂,而DAG上的最长路或者最短路问题又是特别重要的一类问题,很多问题都可以转换成求解DAG上的最长或最短路径问题,因此有必要介绍一下更简便的方法,也就是使用本节介绍的方法。由于DAG最长路和最短路的思想是一致的,因此下面以最长路为例。
本节着重解决两个问题:
- 求整个DAG中的最长路径(即不固定起点跟终点)
- 固定终点,求DAG的最长路径。
先讨论第一个问题:**给定一个有向无环图,怎样求解整个图的所有路径中权值之和最大的那条。**如图11-6所示,B->D->F->I就是该图的最长路径,长度为9。
针对这个问题,令dp[i]表示从i号顶点出发能获得的最长路径长度,这样所有dp[i]的最大值就是整个DAG的最长路径长度。
那么怎么求解dp数组呢?注意到dp[i]表示从i号顶点出发能获得的最长路径长度,如果从i号顶点出发能直接到达顶点j1,j2,…jk,而dp[j1],dp[j2],…,dp[jk]均已知,那么就有dp[i] = max{dp[j] + length[i->j]}
显然,根据上面的思路,需要按照逆拓扑排序来求解dp数组(想一想,为什么?)。但是有没有不求出逆拓扑序列也能计算dp数组的方法呢?当然有,那就是递归。请看下面的代码,其中图使用邻接矩阵的方式存储。
int DP(int i){
if(dp[i] > 0) return dp[i]; // dp[i]已计算得到
for(int j = 0 ; j < n ; j++){
// 遍历i的所有出边
if(G[i