#UVA1347#Tour(DP :双调欧几里得旅行商问题)
来源:互联网 发布:数车的caxa编程 编辑:程序博客网 时间:2024/05/21 19:47
题意:(先转一段描述)
这种旅程即为从最左点开始,严格地从左到右直至最右点,然后严格地从右到左直至出发点。
下图(b)显示了同样的7个点的最短双调路线。求最短路线。
图a 图b
注:在一个单位栅格上显示的平面上的七个点。 a)最短闭合路线,长度大约是24.89。这个路线不是双调的。b)相同点的集合上的最短双调闭合路线。长度大约是25.58。
这是一个算导上的思考题15-1。
很经典的Dp问题,会给出两种思路(两种不同的转移方法)
首先将给出的点排序,关键字x,重新编号,从左至右1,2,3,…,n。
定义dis[i][j],表示结点i到结点j之间的距离。
法一:
定义Dp[i][j],表示从i连到1,再从1连到j,(注意,i>j,且并没有相连。)
对于任意一个点i来说,有两种连接方法,一种是如图(a)所示,i与i-1相连,另一种呢是如图(b),i与i-1不相连。
根据双调旅程,我们知道结点n一定与n相连,那么,如果我们求的Dp[n][n-1],只需将其加上dis[n-1][n]就是最短双调闭合路线。
写出方程式:
Dp[i][j]=Dp[i-1][j]+dis[i][i-1];
Dp[i][i-1]=min(Dp[i][i-1],Dp[i-1][j]+dis[j][i]);
初始状态为Dp[2][1] = dis[2][1];
法二:
定义Dp[i][j]表示第一个人走到i,第二个人走到j,下一个需要访问的点为k,k = max(i, j) + 1;
Dp[k][j] = min(Dp[i][j] + dis[i][k]);
Dp[i][k] = min(Dp[i][j] + dis[j][k]);
Dp[2][1] = Dp[1][2] = dis[1][2];
Code:
法一:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int Max = 1100;const int INF = 0x3f3f3f3f;struct node{ int x, y; bool operator < (const node & X) const{ return x < X.x; }}P[Max + 5];int N;double dis[Max + 5][Max + 5], Dp[Max + 5][Max + 5];bool getint(int & num){ char c; int flg = 1; num = 0; while((c = getchar()) < '0' || c > '9'){ if(c == '-') flg = -1; if(c == -1) return 0; } while(c >= '0' && c <= '9'){ num = num * 10 + c - 48; if((c = getchar()) == -1) return 0; } num *= flg; return 1;}double Get_Dis(int a, int b){ return sqrt(1.0 * (P[a].x - P[b].x) * (P[a].x - P[b].x) + (P[a].y - P[b].y) * (P[a].y - P[b].y));}int main(){ while(getint(N)){ for(int i = 1; i <= N; ++ i) getint(P[i].x), getint(P[i].y); sort(P + 1, P + 1 + N); for(int i = 1; i <= N; ++ i) for(int j = i + 1; j <= N; ++ j) dis[j][i] = dis[i][j] = Get_Dis(i, j); Dp[2][1] = dis[1][2]; for(int i = 3; i <= N; ++ i){ Dp[i][i - 1] = 1.0 * INF; for(int j = 1; j < i - 1; ++ j){ Dp[i][j] = Dp[i - 1][j] + dis[i - 1][i]; Dp[i][i - 1] = min(Dp[i][i - 1], Dp[i - 1][j] + dis[i][j]); } } double Ans = 1.0 * INF; for(int i = 1; i < N; ++ i) Ans = min(Ans, Dp[N][i] + dis[i][N]); printf("%.2lf\n", Ans); } return 0;}
法二:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<vector>#include<map>#include<algorithm>using namespace std;const int Max = 1000;struct node{ double x, y; bool operator < (const node & X) const{ return x < X.x; }}P[Max + 5];int N;double Dp[Max + 5][Max + 5], p[Max + 5][Max + 5];bool getint(int & num){ char c; int flg = 1; num = 0; while((c = getchar()) < '0' || c > '9'){ if(c == '-') flg = -1; if(c == -1) return 0; } while(c >= '0' && c <= '9'){ num = num * 10 + c - 48; if((c = getchar()) == -1) return 0; } num *= flg; return 1;}double Get_Dis(int a, int b){ return sqrt(1.0 * (P[a].x - P[b].x) * (P[a].x - P[b].x) + (P[a].y - P[b].y) * (P[a].y - P[b].y));}int main(){ while(getint(N)){ for(int i = 1; i <= N; ++ i) scanf("%lf%lf", &P[i].x, &P[i].y); for(int i = 1; i <= N; ++ i) for(int j = i + 1; j <= N; ++ j) p[i][j] = p[j][i] = Get_Dis(i, j); for(int i = 0; i <= N; ++ i) for(int j = 0; j <= N; ++ j) Dp[i][j] = 1e12; Dp[1][2] = Dp[2][1] = p[1][2]; for(int i = 1; i <= N; ++ i) for(int j = 1; j <= N; ++ j) if(i != j){ int k = max(i, j) + 1; Dp[k][j] = min(Dp[k][j], Dp[i][j] + p[i][k]); Dp[i][k] = min(Dp[i][k], Dp[i][j] + p[k][j]); } printf("%.2lf\n", Dp[N][N - 1] + p[N][N - 1]); }}
- #UVA1347#Tour(DP :双调欧几里得旅行商问题)
- UVA1347-Tour 双调欧几里得旅行商问题 - 递归记忆实现
- POJ2677 DP tour 双调欧几里得旅行商问题
- 欧几里得旅行商问题uva1347
- 1347 - Tour (双调欧几里得旅行商问题)
- uva 1347 - Tour(双调欧几里得旅行商问题)
- POJ 2677 tour(双调欧几里得旅行商问题)
- UVA 1347 Tour (双调欧几里得旅行商问题)
- UVALive - 3305 Tour 双调欧几里得旅行商问题
- UVA 1347 Tour(双调欧几里得旅行商问题)
- UVA - 1347 Tour 双调欧几里得旅行商问题
- 双调欧几里得旅行商问题 UVA 1347 Tour
- UVA 1347 Tour(双调欧几里得旅行商)
- UVA 1347(POJ 2677) Tour(双调欧几里得旅行商问题)
- 双调欧几里得旅行商问题【sicily 1163 && poj 2677.Tour】
- [ACM] POJ 2677 Tour (动态规划,双调欧几里得旅行商问题)
- UVA 1347(POJ 2677)Tour(双调欧几里得旅行商问题)
- POJ-2677 Tour(双调欧几里得旅行商问题)(动态规划)
- git工作流
- 命令汇总
- 修改Spring Boot的运行端口号
- mysql分区功能详细介绍,以及实例
- 将vim打造成IDE总结(一)
- #UVA1347#Tour(DP :双调欧几里得旅行商问题)
- Java数据类型
- leetcode 144. Binary Tree Preorder Traversal
- Python-web开发验证码的制作
- WebView直接访问手机版,
- canvas的save,restore方法
- jquery 的datatable的属性说明
- Android常用控件 一(文本控件,android资源,selector选择器)
- 【sqoop】 Sqoop详细介绍包括:sqoop命令,原理,流程