–author: Answeror
原帖 http://www.answeror.com/archives/28464
—title: [PKU][2677][Tour][HDU][2224][The shortest path]
—-link: http://acm.pku.edu.cn/JudgeOnline/problem?id=2677
—-link: http://acm.hdu.edu.cn/showproblem.php?pid=2224
—-date: 2009-09-01
-problem: 双调欧几里德旅行商问题.
solution: DP
—-code: http://docs.google.com/View?id=dgtsspfh_74gwg24nhk
著名的双调欧几里德旅行商问题, [算法导论][P217]有介绍. 本题把一来一回转化成两个人同时从左向右走.
这题有O(n^2)和O(n^3)的算法, 状态设置都是一样的:
设A为走得快的, B为走得慢的.
f[i][j]表示A走到i, B走到j时的最优值.
先说说O(n^3)的状态转移:
若i=j, 则f[i][j] = f[i][i-1] + dis[i-1][i]
若i=j+1, 则f[i][j] = min{f[j][k] + dis[k][i]}
若i>j+1, 则f[i][j] = f[i-1][j] + dis[i][j]
在网上转了一圈, 不知道原作者是谁, 反正很多人就把那篇文章转载下来了, 问题是那篇文章里首先把算法导论上的话原封不动贴上去, 然后说本题的DP时间复杂度是O(n^2)的, 然后又给出了上述的O(n^3)的状态转移, 更要命的是作者竟然把第二种情况的那个min给漏了…最后只在(http://www.cppblog.com/qywyh/archive/2007/04/20/22399.html)看到了一篇正解. O(n^2)的状态转移如下:
f[i+1][i] = min{f[i+1][i], f[i][j]+dis[j][i+1]}
f[i+1][j] = min{f[i+1][j], f[i][j]+dis[i][i+1]}
0<=j<i
注意这两种转移方程前者是由前趋推出当前状态, 而后者是由当前状态推出后继, 且后者的DP阶段性更加明确, 直白点说就是按横坐标从左向右扫过去, 新来的点可以给A也可以给B, 于是就推出了两个后继. 落实到编码上要注意后者需要初始化数组为INF, 而前者不需要. 不明白这两种DP方式的请参见刘汝佳的黑书.
Related posts 树的最小支配集 (4) {SCU}{3774}{B-number} (0) {HDU}{3632}{A Captivating Match} (0) [ZJU][ZOJ][ZOJ Monthly, August 2009] (4) [ZJU][3231][Apple Transportation] (1)