hdu 2224(双调旅行商问题)
来源:互联网 发布:java web项目访问路径 编辑:程序博客网 时间:2024/06/16 15:02
The shortest path
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Before you reach the rightmost point Pn, you can only visit the points those have the bigger x-coordinate value. For example, you are at Pi now, then you can only visit Pj(j > i). When you reach Pn, the rule is changed, from now on you can only visit the points those have the smaller x-coordinate value than the point you are in now, for example, you are at Pi now, then you can only visit Pj(j < i). And in the end you back to P1 and the tour is over.
You should visit all points in this tour and you can visit every point only once.
31 12 33 1
6.47Hint: The way 1 - 3 - 2 - 1 makes the shortest path.解题思路:这道题目是一道双调旅行商问题:欧几里德旅行商问题是对平面上给定的n个点的确定一条连接各点的最短闭合旅程的问题。图a给出了一个7个点问题的解。这个问题的一般形式是NP完全的,故其解需要多余多项式的时间。
J.L.Bentley建议通过只考虑双调旅程来简化问题,这种旅程即为从最左点开始,严格地从左到右直至最右点,然后严格地从右到左直至出发点。图b显示了同样的7个点问题的最短双调路线。在这种情况下,多项式时间的算法是可能的。
描述一个确定最优双调路线的O(n^2)时间的算法。可以假设任何两点的x坐标都不相同。
一个人从最左点开始,严格地从左到右直至最右点,然后从右到左直至出发点,可以等价为两个人同时从最左点,严格地从左到右经历不同路径到达最右点。假设这两个人为A和B,且A总是走在B后面。设Pij表示A走到pi、B走到pj时两人所经过的最短双调路径,根据假设,可得i<=j。又设dp[i, j]表示最短双调路径Pij的长度,dis[i, j]表示点pi到点pj的直线距离,则:dp[1, 2]=dis[1, 2]当i=j时,即A和B处于同一点,dp[i, j]=dp[i, i]=dp[i-1, i]+dis[i-1, i]当i=j-1时,即A在B紧邻的靠后一点,dp[i, j]=dp[j-1, j]=min(1<=k<j-1){dp[k, j-1]+dis[k, j]} 当i<j-1时,即A在B后且相隔多个点,dp[i, j]=dp[i, j-1]+dis[j-1, j]
由几何学知识可得,如果中间路径A和B经历了同一点,则这条路径肯定不是最短路径,故i=j的情况只可能用来计算b[n, n]=b[n-1, n]+d[n-1, n]。
这里最难理解的是当i=j-1时,按照定义的dp来讲,dp[k][j-1]应该是A走到k,B走到j-1,那这样怎么会走到i的呢?其实这里A和B的位置不是固定的,这里实际上是把之前k给了A,j-1给了B,因为A与B两者只差一个位置,如果只是从j-1转移到j的话,那么就会走重复的点,肯定不能这样,由于只要知道A与B的路径之和就行了,所以A与B的位置并不会固定死了。这个状态转移确实要多想想。
AC:#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int inf = 0x3f3f3f3f;int n;struct node{double x,y;}pos[205];double dp[205][205];double distance(int i,int j){double tmp;tmp = (pos[i].x - pos[j].x)*(pos[i].x - pos[j].x) + (pos[i].y - pos[j].y)*(pos[i].y - pos[j].y);return sqrt(tmp);}int main(){while(scanf("%d",&n)!=EOF){for(int i = 1; i <= n; i++)scanf("%lf %lf",&pos[i].x,&pos[i].y);dp[1][2] = distance(1,2);for(int j = 3; j <= n; j++){// i < j-1 dp[i][j] = dp[i][j-1] + distance(j-1,j);for(int i = 1; i < j - 1; i++){dp[i][j] = dp[i][j-1] + distance(j-1,j);}dp[j-1][j] = inf;//i = j-1 dp[i][j] = min{dp[k][i]+distance(k,j)}for(int i = 1; i < j - 1; i++){double tmp = dp[i][j-1] + distance(i,j);if(tmp < dp[j-1][j])dp[j-1][j] = tmp;}}dp[n][n] = dp[n-1][n] + distance(n-1,n);printf("%.2lf\n",dp[n][n]);}return 0;}
- hdu 2224(双调旅行商问题)
- HDU 4824 双调旅行商问题
- HDU 2224 The shortest path 双调旅行商问题
- hdu 2224 双调欧几里得旅行商问题tsp
- hdu 2224 经典DP 双调旅行商问题
- HDU 2224 The shortest path(双调欧几里得旅行商问题)
- hdu 2224 The shortest path 双调欧几里得旅行商问题(动态规划)
- hdu 2224 The shortest path(双调欧几里得旅行商问题)
- 双调欧几里得旅行商问题 hdu 2224 |hdu 4824 [动态规划]
- hdu 2224 && poj 2677 (旅行商问题)
- hdu 4824 Disk Schedule(双调欧几里得旅行商问题)
- Hdu 4824 Disk Schedule (双调欧几里得旅行商问题)
- hdu 3001 Travelling (旅行商问题)
- 双调欧几里德旅行商问题--hdu 2224 The shortest path --- POJ 2677Tour
- HDU - 2224 The shortest path (双调欧几里德旅行商问题)
- HDU 4568 旅行商问题
- 双调旅行商问题
- 双调旅行商问题
- 优化方法之朗格朗日对偶性
- 三种ViewController跳转的异同
- swift闭包的强引用
- UI工程师-无需编程-免费开发企业APP应用
- iOS个人整理05-应用程序的启动流程--视图控制器ViewController的加载过程--MVC架构
- hdu 2224(双调旅行商问题)
- Linux下Nginx的安装与配置
- 看透欲望的本质
- Access Hbase
- iOS 列表页跳转到详细页 详细页隐藏TabBar
- 【iOS】倒计时5分钟
- java 三大特性之封装
- Ubuntu Server安装图形界面--存一份
- gsoap工具的使用