http://acm.hdu.edu.cn/showproblem.php?pid=2224

The shortest path

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 772    Accepted Submission(s): 400
Problem Description
There are n points on the plane, Pi(xi, yi)(1 <= i <= n), and xi < xj (i<j). You begin at P1 and visit all points then back to P1. But there is a constraint:

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.
 
Input
The input consists of multiple test cases. Each case begins with a line containing a positive integer n(2 <= n <= 200), means the number of points. Then following n lines each containing two positive integers Pi(xi, yi), indicating
the coordinate of the i-th point in the plane.
 
Output
For each test case, output one line containing the shortest path to visit all the points with the rule mentioned above.The answer should accurate up to 2 decimal places.
 
Sample Input
3
1 1
2 3
3 1
 
Sample Output
6.47

Hint: The way 1 - 3 - 2 - 1 makes the shortest path.

题意:平面上n个点,确定一条连接各点的最短闭合旅程。这个解的一般形式为NP的(在多项式时间内可以求出)

建议通过只考虑双调旅程(bitonictour)来简化问题,这种旅程即为从最左点开始,严格地从左到右直至最右点,然后严格地从右到左直至出发点。每个点都要走一次,且每个点只能走一次,求最短路径;

设dp[i][j]代表起始点到i的距离+起始点到j的距离,中间没有交叉点,且没有遗漏点(dp[i][j]=dp[j][i]);

当i<j-1的时候,dp[i][j]是从dp[i][j-1]传递过去的,即dp[i][j]=dp[i][j-1]+dis[j-1][j];

当i=j-1的时候,dp[i][j]是由dp[i][k]+dis[k][j]得到的,即dp[i][j]=min(dp[i][j],dp[i][k]+dis[k][j]);
程序:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include"stdio.h"
#include"string.h"
#include"iostream"
#include"map"
#include"string"
#include"queue"
#include"stdlib.h"
#include"algorithm"
#include"math.h"
#define M 222
#define eps 1e-10
#define inf 100000000000000
#define mod 1000000000
#define INF 1000000000
using namespace std;
struct node
{
double x,y;
}p[M];
double dp[M][M],dis[M][M];
double min(double a,double b)
{
return a<b?a:b;
}
double Len(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int n,i,j;
while(scanf("%d",&n)!=-1)
{
for(i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p,p+n,cmp);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
dis[i][j]=Len(p[i],p[j]);
dp[0][1]=dis[0][1];
for(j=2;j<n;j++)
{
for(i=0;i<j-1;i++)
dp[i][j]=dp[i][j-1]+dis[j-1][j];
dp[j-1][j]=inf;
for(i=0;i<j-1;i++)
dp[j-1][j]=min(dp[j-1][j],dp[i][j-1]+dis[i][j]);
}
dp[n-1][n-1]=dp[n-2][n-1]+dis[n-2][n-1];
printf("%.2lf\n",dp[n-1][n-1]);
}
}

双调欧几里得旅行商问题(TSPhdu2224)的更多相关文章

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

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

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

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

  3. POJ2677 Tour(DP+双调欧几里得旅行商问题)

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

  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. NOIP2012拓展欧几里得

    拉板题,,,不说话 我之前是不是说过数据结构很烦,,,我想收回,,,今天开始的数论还要恶心,一早上听得头都晕了 先来一发欧几里得拓展裸 #include <cstdio> void gcd ...

  8. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C.Ray Tracing (模拟或扩展欧几里得)

    http://codeforces.com/contest/724/problem/C 题目大意: 在一个n*m的盒子里,从(0,0)射出一条每秒位移为(1,1)的射线,遵从反射定律,给出k个点,求射 ...

  9. poj 1061 青蛙的约会 拓展欧几里得模板

    // poj 1061 青蛙的约会 拓展欧几里得模板 // 注意进行exgcd时,保证a,b是正数,最后的答案如果是负数,要加上一个膜 #include <cstdio> #include ...

随机推荐

  1. Javascript实现浏览器菜单命令

    每当我们看到别人网页上的打开.打印.前进.另存为.后退.关闭本窗口.禁用右键等实现浏览器命令的链接,而自己苦于不能实现时,是不是感到很遗憾?是不是也想实现?如果能在网页上能实现浏览器的命令,将是多么有 ...

  2. altium designer应用技巧---cyclone IV代芯片底部焊盘问题

    首先对于 altera 公司的FPGA芯片来讲,在cyclone III代以上,芯片的底部增加了一 个焊盘,很多工程师往往以为是散热用,其实不然,底部焊盘需要接地(altera手册上面 明确规定,Th ...

  3. 关于Cocos2d-x中打包图集和使用方法

    准备的过程 1.打开TextruePacker软件 2.把游戏中要使用的图片拖到TextruePacker里面,TextruePacker会自动帮我们排序,让所有小图变成一个大图 3.点击Publis ...

  4. tensorflow中slim模块api介绍

    tensorflow中slim模块api介绍 翻译 2017年08月29日 20:13:35   http://blog.csdn.net/guvcolie/article/details/77686 ...

  5. 解析xml的4种方法详解

    1. 介绍 1)DOM(JAXP Crimson解析器)         DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许 ...

  6. 【面试】hibernate n+1问题

    Hibernate中常会用到set,bag等集合表示1对多的关系, 在获取实体的时候就能根据关系将关联的对象或者对象集取出, 还可以设定cascade进行关联更新和删除.这不得部说hibernate的 ...

  7. RTC终于tm的通了

     ITDS(1316336566) 2014-1-16 10:34:36我们板子上用的是pcf8563默认没使用这个,用图形界面选择下这个完以后,在配置下就这两步骤ITDS(1316336566) 2 ...

  8. 关于android 调用网页隐藏地址栏

    首先创建项目,在main.xml里 添加好WebView控件R.id为webview1. HelloWebView.java 代码 package liu.ming.com; import andro ...

  9. VC++ 打开文件或文件夹对话框的实现方法

    实际工作开发中,由于各种应用,我们需要调用系统的打开文件对话框或者打开文件夹对话框,或两者兼有.特总结了常用的实现方法,仅供开发参考. 1. 打开文件对话框 常用的方法是使用系统的CFileDialo ...

  10. 下载mysql server安装包的时候,不登录oracle账号,实现下载

    需求描述: 之前下载mysql安装包的时候,都是使用oracle账号进行登录下载,最近看到可以不登录账号 就实现下载的方法,在此记录下. 操作过程: 1.选择mysql linux服务器上的安装包,点 ...