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. Oracle 存储过程错误之PLS-00201: 必须声明标识符

    转自:http://blog.csdn.net/u010678947/article/details/20702149 错误: ORA-06550: 第 1 行, 第 7 列: PLS-00201: ...

  2. e667. 在给定图像中创建缓冲图像

    An Image object cannot be converted to a BufferedImage object. The closest equivalent is to create a ...

  3. Stream(流)的基本操作

    //把流转化为文件  public static void StreamToFile(Stream stream, string filepath)        {            byte[ ...

  4. RAC:Oracle11gR2:群集的起、停、状态查询

    一:查看群集的状态 1.0.1 使用crsctl status resource [-t] 1.0.2 使用crs_stat [-t] 1.0.1 使用srvctl status <obj> ...

  5. mybatise 实现同一字段多模糊查询

    mybatise 同一字段多模糊查询 <foreach collection="typeList" index="index" item="it ...

  6. ubuntu13.10更换源

    Ubuntu13.10更新源 不同的网络状况连接以下源的速度不同, 建议在添加前手动验证以下源的连接速度(ping下就行),选择最快的源可以节省大批下载时间. 首先备份源列表: sudo cp /et ...

  7. Java 实现选择排序

    选择排序: 原理:依次从数组最左边取一个元素,与之后的位置上的元素比較,假设大于/小于(取决于须要升序排还是降序排).则保存较大/较小元素的索引 当一轮比較后,将保存的较大/较小元素的索引与 这轮開始 ...

  8. day05<Java语言基础--数组>

    Java语言基础(数组概述和定义格式说明) Java语言基础(数组的初始化动态初始化) Java语言基础(Java中的内存分配以及栈和堆的区别) Java语言基础(数组的内存图解1一个数组) Java ...

  9. POJ 1038 Bug Integrated Inc(状态压缩DP)

    Description Bugs Integrated, Inc. is a major manufacturer of advanced memory chips. They are launchi ...

  10. python2.0 s12 day3

    s12 day3 视频每节的内容 03 python s12 day3 本节内容概要 第三天的主要内容 上节没讲完的: 6.集合 7.collections 1)计数器 2)有序字典 3)默认字典 4 ...