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.
Note: An input/output sample is in the table below. Here there are two data sets. The first one
contains points specified by their x and y coordinates. The second point, for example, has the x
coordinate , and the y coordinate . The result for each data set is the tour length, (6.47 for the first
data set in the given example).
Sample Input Sample Output
6.47
7.89

【分析】:

首先按横坐标递增给所有点排序。

定义状态dp[i][j]表示从点i向n走一条路L1,从点j向n走另一条路L2(如下图,两条路互不相交,并且L1在L2上面),L1 + L2的最小值。程序中用distance(i, j)表示点i到点j的距离。

如何计算dp[i, j]呢?

我们考虑k = max(i, j) + 1这个点,这个点肯定在L1或者L2上。

k在L1上时,k在L2上时,如图

dp[i][j]取这两者最小值即可。

可能还是有点抽象,举个实际的例子吧。

假如i = 5, j = 4。在计算dp[5][4]的时候,考虑6这个点。6只有两种选择,要么在L1上(上面的路),这时候的代价为dp[6][4] + distance(5, 6)。要么在L2上(下面的路),这时候的代价为dp[5][6] + distance(4, 6)。

所以状态转移方程为:dp[i][j] = min(dp[i][k] + distance(j, k),dp[k][j] + distance(i, k))

一、临界情况

1.  i = n: dp[i][j] = distance(j, n)

2.  j = n: dp[i][j] = distance(i, n)

二、其余情况

k = max(i, j) + 1

dp[i][j] = min(dp[i][k] + distance(j, k), dp[k][j] + distance(i,k))

【讲解】:http://blog.sina.com.cn/s/blog_51cea4040100gkcq.html

【代码】:

#include <bits/stdc++.h>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> using namespace std;
const int N = ;
double dp[N][N];
struct node
{
double x, y;
bool operator < (const node& a)
{
return x < a.x; //按横坐标递增给所有点排序
}
}a[N];
//bool cmp(node a,node b)
//{
// return a.x > b.x;
//}
double dis(int i, int j)
{
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
int main()
{
int n;
while(cin >> n)
{
for(int i=; i<=n; i++) cin >> a[i].x >> a[i].y;
sort(a+, a+n+);
memset(dp,,sizeof(dp)); for(int i=n; i>=; i--){
for(int j=n; j>=; j--){
if(i==n && j==n) dp[i][j]=;
else if(j==n) dp[i][j]=dis(i,n);
else if(i==n) dp[i][j]=dis(j,n);
else{
int k=max(i,j)+;
dp[i][j]=min(dp[i][k]+dis(j,k), dp[k][j]+dis(i,k));
}
}
}
printf("%.2f\n", dp[][]);
}
}

UVA 1347 Tour 【双调旅行商/DP】的更多相关文章

  1. UVA 1347 Tour 双调TSP

    TSP是NP难,但是把问题简化,到最右点之前的巡游路线只能严格向右,到最右边的点以后,返回的时候严格向左,这个问题就可以在多项式时间内求出来了. 定义状态d[i][j]表示一个人在i号点,令一个人在j ...

  2. ACM - 动态规划 - UVA 1347 Tour

    UVA 1347 Tour 题解 题目大意:有 \(n\) 个点,给出点的 \(x\).\(y\) 坐标.找出一条经过所有点一次的回路,从最左边的点出发,严格向右走,到达最右点再严格向左,回到最左点. ...

  3. hdu 4281 Judges' response(多旅行商&DP)

    Judges' response Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. UVA - 1347 Tour(DP + 双调旅行商问题)

    题意:给出按照x坐标排序的n个点,让我们求出从最左端点到最右短点然后再回来,并且经过所有点且只经过一次的最短路径. 分析:这个题目刘汝佳的算法书上也有详解(就在基础dp那一段),具体思路如下:按照题目 ...

  5. UVA 1347"Tour"(经典DP)

    传送门 参考资料: [1]:紫书 题意: 欧几里得距离???? 题解: AC代码: #include<bits/stdc++.h> using namespace std; ; int n ...

  6. UVa 1347 Tour

    Tour Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Description   Joh ...

  7. 洛谷P1523 旅行商简化版(DP)

    题目: P1523 旅行商简化版 解析 可以看做是两个人同时从西往东走,经过不一样的点,走到最东头的方案数 设\(f[i][j]\)表示一个人走到i,一个人走到j的最短距离(\(i<j\)) 第 ...

  8. P1523 旅行商简化版

    P1523 旅行商简化版 题目背景 欧几里德旅行商(Euclidean Traveling Salesman)问题也就是货郎担问题一直是困扰全世界数学家.计算机学家的著名问题.现有的算法都没有办法在确 ...

  9. vijosP1014 旅行商简化版

    vijosP1014 旅行商简化版 链接:https://vijos.org/p/1014 [思路] 双线DP. 设ab,ab同时走.用d[i][j]表示ab所处结点i.j,且定义i>j,则有转 ...

随机推荐

  1. 《数据结构》C++代码 堆(优先队列)

    堆,是优先队列最常用的一种实现方式.在优先队列中,每个元素都被赋予了一个优先级,而每次出队时都让优先级最高的元素出队.堆,则是一种存储优先队列的方法,特指以一棵树形式存储的优先队列.最常用的是二叉堆, ...

  2. 【Binary Search Tree Iterator 】cpp

    题目: Implement an iterator over a binary search tree (BST). Your iterator will be initialized with th ...

  3. leetcode 【 Merge Two Sorted Lists 】 python 实现

    题目: Merge two sorted linked lists and return it as a new list. The new list should be made by splici ...

  4. Python 3基础教程3-数学运算

    本文来介绍下Python中的常见数学运算,其实和其他语言一样,加减乘除语法差不多,这里注意下Python中指数的表示方法. # 这里介绍 常见的数学运算 # 加法print(5 + 8) # 减法pr ...

  5. Java基础-6流程控制

    一).选择控制: 选择控制分为两种:if...else...和switch 单分支结构:这是最简单的一种选择结构,它只是简单的判断某个条件是否成立,如果成立就执行一段代码,语句形式为: if(条件表达 ...

  6. HDU 3111 Sudoku ( Dancing Links 精确覆盖模型 )

    推荐两篇学DLX的博文: http://bbs.9ria.com/thread-130295-1-1.html(这篇对DLX的工作过程演示的很详细) http://yzmduncan.iteye.co ...

  7. PHP路径相关 dirname,realpath,__FILE__

    ​比如:程序根目录在:E:\wamp\www 中 1.    __FILE__   当前文件的绝对路径 如果在index.php中调用 则返回  E:\wamp\www\index.php 下面再看一 ...

  8. 为什么实际内存使用量已经超过了memory.soft_limit_in_bytes,但是并没有立即触发try_to_free_pages in try_charge

    kswapd发起的回收过程汇总会通过cgroup的excessed树进行回收,但是这个kwap都是啥时候被唤醒呢?为啥不是mem_cgroup_soft_limit_reclaim 发现在内核在在:p ...

  9. HITOJ 2739 The Chinese Postman Problem(欧拉回路+最小费用流)

    The Chinese Postman Problem My Tags   (Edit)   Source : bin3   Time limit : 1 sec   Memory limit : 6 ...

  10. flutter channel master

    flutter可能是未来跨平台开发的又一技术框架,那么对于一个app,我们不可能完全用flutter来开发,那么就意味着我们需要在已有的Android和iOS代码中去集成flutter.目前这一技术还 ...