Tour
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3929   Accepted: 1761

Description

John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John must determine the shortest closed tour that connects his destinations. Each destination is represented by a point in the plane pi = < xi,yi >. John uses the following strategy: he starts from the leftmost point, then he goes strictly left to right to the rightmost point, and then he goes strictly right back to the starting point. It is known that the points have distinct x-coordinates.
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

The program input is from a text file. Each data set
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

For each set of data, your program should print the
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
思路【转】:
  欧几里得旅行商问题是对平面上给定的n个点确定一条连接各点的最短闭合旅程的问题。如图(a)给出了一个7个点问题的解。这个问题的一般形式是NP完全的,故其解需要多于多项式的时间。

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+双调欧几里得旅行商问题)的更多相关文章

  1. 2014百度之星第二题Disk Schedule(双调欧几里得旅行商问题+DP)

    Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  2. 2014年百度之星程序设计大赛 - 资格赛 1002 Disk Schedule(双调欧几里得旅行商问题)

    Problem Description 有非常多从磁盘读取数据的需求,包含顺序读取.随机读取.为了提高效率,须要人为安排磁盘读取.然而,在现实中,这样的做法非常复杂.我们考虑一个相对简单的场景.磁盘有 ...

  3. 双调欧几里得旅行商问题(TSPhdu2224)

    http://acm.hdu.edu.cn/showproblem.php?pid=2224 The shortest path Time Limit: 1000/1000 MS (Java/Othe ...

  4. hdu 2224 双调欧几里得旅行商问题tsp

    /* 题意:平面上n个点,确定一条连接各点的最短闭合旅程且每个点仅用一次.这个解的一般形式为NP的(在多项式时间内可以求出) 建议通过只考虑双调旅程(bitonictour)来简化问题,这种旅程即为从 ...

  5. 欧几里得旅行商问题 java与c++实现

    双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1 旅行商问题描述:平面上n个点,确定一条连接各点的最短闭合旅程.这个解的一般形式为NP的(在多项式时间内可 ...

  6. 【HDU2224】The shortest path(双调欧几里得dp)

    算法导论上一道dp,挺有趣的.于是就研究了一阵. dp(i, j)代表从左边第一个点到第i个点与从从左边最后一个点(即为第一个点)到j点的最优距离和.于是找到了子状态. 决策过程 dp[i][j] = ...

  7. POJ2677 Tour[DP 状态规定]

    Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4307   Accepted: 1894 Description ...

  8. poj2677 Tour

    题意: 双调欧几里得旅行商问题. 思路: dp.定义dp[i][j](i <= j)为从点j从右向左严格按照x坐标递减顺序走到点1,之后再从点1从左向右严格按照x坐标递增的顺序走到点i,并且在此 ...

  9. code1213 解的个数 扩展欧几里得

    很不错的题,加深了我对exgcd的理解 (以前我认为做题就是搜索.dp...原来数学也很重要) 理解了几个小时,终于明白了.但我什么都不打算写. 看代码吧: #include<iostream& ...

随机推荐

  1. Chrome 开发工具 Javascript 调试技巧

    http://www.w3cplus.com/tools/dev-tips.html 一.Sources 面板介绍: Sources 面板分为左中右 3 部分左:Sources 当前页面加载的资源列表 ...

  2. 16SpringMvc_在业务控制方法中写入User,Admin多个模型收集参数——引出问题

    上面文章时普通的业务那个方法中收集一个实体类,这篇文章想收集两个实体类. 文本要做的是:在person.jsp页面上,有两个表单.分别是普通用户和管理员用户的表单(普通用户的表单和管理员用户的表单里面 ...

  3. 课题:如何培养自己的SEO资源

    课题:如何培养自己的SEO资源 问:做SEO最重要的是什么?[针对性的流量]答:看获取一样东西的门槛.稀缺性,人人可得价值不大外链 内容 流量[正确]针对性的自然流量是用户自愿带来的,价值高,能形成购 ...

  4. 一些正则验证-JS

    Validation = { textCount: function(field, counter, maxLimit) { var message = $(field).val(); if ($(f ...

  5. SpringMVC中的@PathVariable

    @PathVariable是用来动态获得url中的参数的,代码示例如下: 可以在代码中获得lev_1.lev_2和target参数的值看一下 // 支持跳转到WEB-INF/目录下二层目录 @Requ ...

  6. 使用C#改变鼠标的指针形状

    1.在一个无标题的窗体中用MOUSEMOVE事件判断鼠标坐标是否到达窗体的边缘,如果是的话将鼠标指针改为可调整窗体大小的双向箭头. private   void   Form1_MouseMove(o ...

  7. Got a packet bigger than 'max_allowed_packet' bytes

    昨天用导入数据的时候发现有的地方有这个错误.后来才发现我用RPM包装的MYSQL配置文件里面有old_passwords=1去掉就可以了. Got a packet bigger than ‘max_ ...

  8. TinyFrame升级之二:数据底层访问部分

    在上一篇中,我列举了框架的整体结构,下面我们将一一说明: 首先需要说明的是TinyFrame.Data. 它主要用于处理数据库底层操作.包含EF CodeFirst,Repository,Unitof ...

  9. 基于EventAggregator的事件发布及订阅

    EventAggregator简介 EventAggregator是Prism中专门处理ViewModel与ViewModel之间事件传递的类对象,它提供了针对事件的发布方法和订阅方法,所以可以非常方 ...

  10. Android清单文件详解(三)----应用程序的根节点<application>

    <application>节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在<manifest>节点下.通过<application>节 ...