P1523 旅行商简化版

题目背景

欧几里德旅行商(Euclidean Traveling Salesman)问题也就是货郎担问题一直是困扰全世界数学家、计算机学家的著名问题。现有的算法都没有办法在确定型机器上在多项式时间内求出最优解,但是有办法在多项式时间内求出一个较优解。

为了简化问题,而且保证能在多项式时间内求出最优解,J.L.Bentley提出了一种叫做bitonic tour的哈密尔顿环游。它的要求是任意两点(a,b)之间的相互到达的代价dist(a,b)=dist(b,a)且任意两点之间可以相互到达,并且环游的路线只能是从最西端单向到最东端,再单项返回最西端,并且是一个哈密尔顿回路。

题目描述

著名的NPC难题的简化版本

现在笛卡尔平面上有n(n<=1000)个点,每个点的坐标为(x,y)(-2^31<x,y<2^31,且为整数),任意两点之间相互到达的代价为这两点的欧几里德距离,现要你编程求出最短bitonic tour。

输入输出格式

输入格式:

第一行一个整数n

接下来n行,每行两个整数x,y,表示某个点的坐标。

输入中保证没有重复的两点,

保证最西端和最东端都只有一个点。

输出格式:

一行,即最短回路的长度,保留2位小数。

输入输出样例

输入样例#1:

7
0 6
1 0
2 3
5 4
6 1
7 5
8 2
输出样例#1:

25.58
 

分析:

下面提供两种方法,刷表法和填表法
 
1、刷表法
代码是从前往后刷表

【1】题意:旅行商问题,不过要求只能单向走,就是有n个地方,要求从西往东,到最东面的地方,在从东往西返回,经过每个点一次,求最短路径

【2】分析:由于有了方向的限制,这题不再是NP难题,我们可以假设有两个人一起从西往东走,走过的点不能重复,这样就有f[ i ][ j ]表示第一个人走到i,第二个人走到j 的最短路径,要求i<j,且0到j的点都被经过了,这样很容易想到,j+1的点不是被第一个人走,就是被第二个人走,所以有转移方程f[ i ][ j+1]=min{ f[ i ] [ j ]+d[ j ] [ j +1] } f[ j ] [ j+1 ]=min{ f[ i ][ j ]+d[ i ][ j+1 ] },第一个转移方程很容易理解,第二个方程可以这么理解,两个人可以指前面一个人,和后面一个人,当后面的人走到前面,当然就对换过来了,不影响结果

【3】最后,预处理f[ 0 ][ 1]还有扫描 一遍答案就行了,这题算是一类DP吧,思路挺有启发性的

 #include <cmath>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int mm=;
struct data
{
double x,y;
}g[mm];
double d[mm][mm],f[mm][mm];
int i,j,k,n;
bool cmp(const data &a,const data &b)
{
return a.x<b.x;
}
double mdis(const data &a, const data &b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
scanf("%d",&n);
for(i=;i<n;++i)
scanf("%lf%lf",&g[i].x,&g[i].y);
sort(g,g+n,cmp);
for(i=;i<n;++i)
for(j=i+;j<n;++j)
{
d[i][j]=mdis(g[i],g[j]);
f[i][j]=1e30;
}
f[][]=d[][];
for(i=;i<n;++i)
for(j=i+;j<n;++j)
{
f[i][j+]=min(f[i][j+],f[i][j]+d[j][j+]);
f[j][j+]=min(f[j][j+],f[i][j]+d[i][j+]);
}
double ans=1e30;
for(j=;j<n-;++j)
ans=min(ans,f[j][n-]+d[j][n-]);
printf("%.2lf\n",ans);
return ;
}

2、填表法

代码是从后往前填表

遍历一整个图, 从开始位置走到末尾,再走回开始位置,并且不能重复;

由于题目并没有对输入数据按X从小到大排序,所以先排序,然后预处理出每两个点之间的欧几里得距离。

f(i,j)表示 从 1->max(i,j) 已经全部遍历切没有重复的最短路;

那么可知F(i , j) = F(j , i); 于是就规定 i > j;

如果 i = n - 1; 那么就强行将j跳到末尾位置;f(i, j) = dis(i, n) + dis(j, n);

其余可知 f(i,j) = max ( f(i+1, j) + dis(i, i +1), f(i+1, i) + dis(j, i+1)) 原本应写成f(i, i+1), 但由于规定所以写成这样;

最终状态为f(2, 1);

接着就是naive的输出啦;

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
typedef long long Lovelive;
using namespace std; const int maxn = + ;
int n;
struct Node {
double x, y;
}node[maxn];
double dis[maxn][maxn], f[maxn][maxn]; bool cmp(Node a, Node b) {
return a.x < b.x;
} int main() {
scanf("%d",&n);
for(int i = ; i <= n; i++) scanf("%lf%lf",&node[i].x,&node[i].y);
sort(node+, node+n+, cmp);
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
dis[i][j] = sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x) + (node[i].y-node[j].y)*(node[i].y-node[j].y)); for(int i = n-; i >= ; i--)
for(int j = ; j < i; j++)
if(i == n-) f[i][j] = dis[i][n] + dis[j][n];
else f[i][j] = min (f[i+][j] + dis[i][i+], f[i+][i] + dis[j][i+]);
printf("%.2lf",f[][] + dis[][]);
return ;
}
 
 
 
 
 

P1523 旅行商简化版的更多相关文章

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

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

  2. [vijos P1014] 旅行商简化版

    昨天早上上课讲旅行商问题,有点难,这周抽空把3^n的算法码码看.不过这个简化版已经够折腾人了. 其一不看解析不知道这是双进程动态规划,不过我看的解析停留在f[i,j]表示第一个人走到i.第二个人走到j ...

  3. vijosP1014 旅行商简化版

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

  4. 洛谷【P1523】旅行商的背包(算法导论 15-1) 题解

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

  5. 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法

    若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...

  6. 洛谷P1782 旅行商的背包[多重背包]

    题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...

  7. 2016全国研究生数学建模A题多无人机协同任务规划——基于分布式协同多旅行商MTSP遗传算法

    MTSP问题是指:有Ⅳ个城市,要求旅行商到达每个城市各一次,且仅一次,并[旦 1到起点,且要求旅行路线最短.而多旅行商问题M个旅行商从同一个城市(或多个城市)出发.分羽走一条旅路线,且总路程缀短.有关 ...

  8. Bzoj3352 [ioi2009]旅行商

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 89  Solved: 36 Description 旅行商认定如何优化旅行路线是一个非常棘手的计算问题 ...

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

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

随机推荐

  1. AcWing 232. 守卫者的挑战 (期望DP)打卡

    题目:https://www.acwing.com/problem/content/description/234/ 题意:有n次挑战,每次挑战获胜可以得到一个地图碎片值为-1  或者  可以得到一个 ...

  2. HDU 1828 线段树+扫描线(计算矩形周长并)

    题意:给你n个矩形,然后矩形有可能重叠,要你求周长 思路:首先碰到这种矩形在数轴上那么第一反应应该想到的是扫描线, 做周长我们有两种方法 第一种,我们可以分开两部分求,第一遍求x轴上的贡献,第二遍求y ...

  3. AcWing 215. 破译密码 (莫比乌斯反演)打卡

    达达正在破解一段密码,他需要回答很多类似的问题: 对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d. 作为达达的同学,达达希望得到你的帮助. ...

  4. 关于Burp Suite不能抓包的解决方法

    一.Burp Suite有时能抓到包,有时不能抓到包 解决方法: 出现这种问题的原因就是代理没有设置成全局的,只是设置成了局部的. 打开IE浏览器,依次打开工具->Internet 属性-> ...

  5. 耗时十个月的德国APS,教会我的学习方法

    考过了准备了10个月的Aps ,想送给关注我的8175个粉丝,一份礼物,感谢你们看的起我,对我的支持和关注. 这份礼物,我就大言不惭的称之为:达令的学习方法. 我的考试经历:高考两次,中戏艺考三试,导 ...

  6. 浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变【转】

    浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变 前言:2009年10月23日,微软高调发布了其最新一代操作系统——Windows7,这款操作系统相对于 ...

  7. js匿名函数测试

    js匿名函数测试 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  8. eclipse 集成 STS 插件

    eclipse 集成 STS 插件 想新建一个 Spring Boot 工程,发现没有,如图:(展示的是集成之后的) eclipse 要和 sts 版本对应的,进入http://spring.io/t ...

  9. kafka安装指导

    本篇博客主要讲解在虚拟机安装之后,从如下五个方面进行讲解kafka的安装过程. (1)如何配置虚拟机网络 (2)如何安装JDK (3)如何安装zookeeper (4)如何安装kafka (5)kaf ...

  10. vue - blog开发学习2

    首页博客列表的开发 1.修改index.vue,使能够支持列表功能 <template> <div> <PostList v-for="(item,index) ...