POJ2677 Tour(DP+双调欧几里得旅行商问题)
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3929 | Accepted: 1761 |
Description
Write a program that, given a set of n points in the
plane, computes the shortest closed tour that connects the points according to
John's strategy.
Input
in the file stands for a particular set of points. For each set of points the
data set contains the number of points, and the point coordinates in ascending
order of the x coordinate. White spaces can occur freely in input. The input
data are correct.
Output
result to the standard output from the beginning of a line. The tour length, a
floating-point number with two fractional digits, represents the result. An
input/output sample is in the table below. Here there are two data sets. The
first one contains 3 points specified by their x and y coordinates. The second
point, for example, has the x coordinate 2, and the y coordinate 3. The result
for each data set is the tour length, (6.47 for the first data set in the given
example).
Sample Input
3
1 1
2 3
3 1
4
1 1
2 3
3 1
4 2
Sample Output
6.47
7.89 参考博客:http://www.cnblogs.com/-sunshine/archive/2012/07/23/2605251.html
J.L. Bentley 建议通过只考虑双调旅程(bitonic tour)来简化问题,这种旅程即为从最左点开始,严格地从左到右直至最右点,然后严格地从右到左直至出发点。下图(b)显示了同样的7个点的最短双调路线。在这种情况下,多项式的算法是可能的。事实上,存在确定的最优双调路线的O(n*n)时间的算法。
图a 图b
注:在一个单位栅格上显示的平面上的七个点。 a)最短闭合路线,长度大约是24.89。这个路线不是双调的。b)相同点的集合上的最短双调闭合路线。长度大约是25.58。
这是一个算导上的思考题15-1。
首先将给出的点排序,关键字x,重新编号,从左至右1,2,3,…,n。
定义p[i][j],表示结点i到结点j之间的距离。
定义d[i][j],表示从i连到1,再从1连到j,(注意,i>j,且并没有相连。)
对于任意一个点i来说,有两种连接方法,一种是如图(a)所示,i与i-1相连,另一种呢是如图(b),i与i-1不相连。
根据双调旅程,我们知道结点n一定与n相连,那么,如果我们求的d[n][n-1],只需将其加上p[n-1][n]就是最短双调闭合路线。
根据上图,很容易写出方程式:
dp[i][j]=dp[i-1][j]+dist[i][i-1]; i这一点是i+1走到的
dp[i][i-1]=min(dp[i][i-1],dp[i-1][j]+dist[j][i]); i这一点是从j走到的,找到j的最小值
自己的理解:刘汝佳书上的思路看懂了,但是老卡,抽空在想想他的思路,这个思路也好理解,在dp[i][j]这个位置,到下一个i+1,有两种情况要么是i走到的,要么是j走到的,如果是i走到的就对应第一个转移方程,如果是j走到的 dp[i][j] == dp[j][i],所以对应第二个方程
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX = + ;
struct points
{
double x,y;
};
points point[MAX];
double d[MAX][MAX];
int cmp(points a, points b)
{
return (b.x - a.x > 0.00001);
}
double Min(double a, double b)
{
if(a - b > 0.00001)
return b;
else
return a;
}
double dist(int a, int b)
{
return sqrt( (point[a].x - point[b].x) * (point[a].x - point[b].x) + (point[a].y - point[b].y) * (point[a].y - point[b].y));
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = ; i <= n; i++)
scanf("%lf%lf", &point[i].x, &point[i].y);
sort(point + , point + n + , cmp);
if(n == )
{
printf("0\n");
continue;
}
d[][] = ;
for(int i = ; i <= n; i++)
d[i][] = dist(i, ); for(int i = ; i < n; i++)
{
d[i + ][i] = 10000000.0;
for(int j = ; j < i; j++)
{
d[i + ][j] = d[i][j] + dist(i, i + );
d[i + ][i] = Min(d[i + ][i], d[i][j] + dist(j,i + ));
}
}
printf("%.2lf\n", d[n][n - ] + dist(n - , n));
}
return ;
}
POJ2677 Tour(DP+双调欧几里得旅行商问题)的更多相关文章
- 2014百度之星第二题Disk Schedule(双调欧几里得旅行商问题+DP)
Disk Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 2014年百度之星程序设计大赛 - 资格赛 1002 Disk Schedule(双调欧几里得旅行商问题)
Problem Description 有非常多从磁盘读取数据的需求,包含顺序读取.随机读取.为了提高效率,须要人为安排磁盘读取.然而,在现实中,这样的做法非常复杂.我们考虑一个相对简单的场景.磁盘有 ...
- 双调欧几里得旅行商问题(TSPhdu2224)
http://acm.hdu.edu.cn/showproblem.php?pid=2224 The shortest path Time Limit: 1000/1000 MS (Java/Othe ...
- hdu 2224 双调欧几里得旅行商问题tsp
/* 题意:平面上n个点,确定一条连接各点的最短闭合旅程且每个点仅用一次.这个解的一般形式为NP的(在多项式时间内可以求出) 建议通过只考虑双调旅程(bitonictour)来简化问题,这种旅程即为从 ...
- 欧几里得旅行商问题 java与c++实现
双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1 旅行商问题描述:平面上n个点,确定一条连接各点的最短闭合旅程.这个解的一般形式为NP的(在多项式时间内可 ...
- 【HDU2224】The shortest path(双调欧几里得dp)
算法导论上一道dp,挺有趣的.于是就研究了一阵. dp(i, j)代表从左边第一个点到第i个点与从从左边最后一个点(即为第一个点)到j点的最优距离和.于是找到了子状态. 决策过程 dp[i][j] = ...
- POJ2677 Tour[DP 状态规定]
Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4307 Accepted: 1894 Description ...
- poj2677 Tour
题意: 双调欧几里得旅行商问题. 思路: dp.定义dp[i][j](i <= j)为从点j从右向左严格按照x坐标递减顺序走到点1,之后再从点1从左向右严格按照x坐标递增的顺序走到点i,并且在此 ...
- code1213 解的个数 扩展欧几里得
很不错的题,加深了我对exgcd的理解 (以前我认为做题就是搜索.dp...原来数学也很重要) 理解了几个小时,终于明白了.但我什么都不打算写. 看代码吧: #include<iostream& ...
随机推荐
- 【转】【C#】【Thread】Mutex 互斥锁
Mutex:互斥(体) 又称同步基元. 当创建一个应用程序类时,将同时创建一个系统范围内的命名的Mutex对象.这个互斥元在整个操作系统中都是可见的.当已经存在一个同名的互斥元时,构造函数将会输出一个 ...
- Google play billing(Google play 内支付)
准备工作 1. 通过Android SDK Manager下载extras中的Google Play services和Google Play Billing Library两个包. 2. 把下载的. ...
- python socket发送魔法包网络唤醒开机.py
python socket发送魔法包网络唤醒开机.py 现在的电脑应该都普遍支持有线网络的WOL了,支持无线网络唤醒的电脑,可能比较少. """ python socke ...
- .Net 内存溢出(System.OutOfMemoryException)的常见情况和处理方式总结
.Net 内存溢出(System.OutOfMemoryException)的常见情况和处理方式总结 在什么情况下会出现OutOfMemonryException呢? 在我们试图新建一个对象时,而垃圾 ...
- 虚拟现实的三维时态GIS模式研究
- The ServiceClass object does not implement the required method in the following form: OMElement sayHello(OMElement e)
今天遇到一件诡异的事情,打好的同一个aar包,丢到测试环境tomcat,使用soapui测试,正常反馈结果. 丢到本地tomcat,使用soapui测试,始终报以下错误. <soapenv:En ...
- Jdev Run Page 没有反应
从旧电脑把原有的Jdeveloper完整的拷贝至新电脑,且已完整配置JDEV_USER_HOME,JAVA_HOME等环境变量, Run Page报以下错误. [Starting OC4J using ...
- CSS 动画之九-会呼吸的信封
新年已经到来,各个网站都举办着各种不同类型的活动,'会呼吸的信封'有可能就是你遇到的其中一种.其实就是一个信封的样式,在封口处加上开合开合的动画效果,吸引用户去打开这个信封,点击后可能会送红包,优惠券 ...
- Activiti系列:是否可以让某些流程的信息写到历史表,而另外一些不写?
一.起因 打算使用activiti的定时启动事件来定时启动流程,然后再在该流程中针对每个用户启动另外一个流程实例来计算每个用户的实时账单,系统的用户数一般是1000~2000(此处假设是200 ...
- Activiti系列:如何把Activiti工程转换为maven工程以解决依赖项找不到的问题
在eclipse中安装了Activiti插件之后,就可以新建Activiti工程,但是在实际使用时发现,在该工程中间新建Activiti Diagram,绘制好该图形之后,右键,新建单元测试,选择ju ...