P1523 旅行商简化版
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位小数。
输入输出样例
7
0 6
1 0
2 3
5 4
6 1
7 5
8 2
25.58
分析:
【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 旅行商简化版的更多相关文章
- 洛谷P1523 旅行商简化版(DP)
题目: P1523 旅行商简化版 解析 可以看做是两个人同时从西往东走,经过不一样的点,走到最东头的方案数 设\(f[i][j]\)表示一个人走到i,一个人走到j的最短距离(\(i<j\)) 第 ...
- [vijos P1014] 旅行商简化版
昨天早上上课讲旅行商问题,有点难,这周抽空把3^n的算法码码看.不过这个简化版已经够折腾人了. 其一不看解析不知道这是双进程动态规划,不过我看的解析停留在f[i,j]表示第一个人走到i.第二个人走到j ...
- vijosP1014 旅行商简化版
vijosP1014 旅行商简化版 链接:https://vijos.org/p/1014 [思路] 双线DP. 设ab,ab同时走.用d[i][j]表示ab所处结点i.j,且定义i>j,则有转 ...
- 洛谷【P1523】旅行商的背包(算法导论 15-1) 题解
P1523 旅行商简化版 题目背景 欧几里德旅行商\((Euclidean Traveling Salesman)\)问题也就是货郎担问题一直是困扰全世界数学家.计算机学家的著名问题.现有的算法都没有 ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
- 洛谷P1782 旅行商的背包[多重背包]
题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...
- 2016全国研究生数学建模A题多无人机协同任务规划——基于分布式协同多旅行商MTSP遗传算法
MTSP问题是指:有Ⅳ个城市,要求旅行商到达每个城市各一次,且仅一次,并[旦 1到起点,且要求旅行路线最短.而多旅行商问题M个旅行商从同一个城市(或多个城市)出发.分羽走一条旅路线,且总路程缀短.有关 ...
- Bzoj3352 [ioi2009]旅行商
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 89 Solved: 36 Description 旅行商认定如何优化旅行路线是一个非常棘手的计算问题 ...
- hdu 4281 Judges' response(多旅行商&DP)
Judges' response Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- AcWing 232. 守卫者的挑战 (期望DP)打卡
题目:https://www.acwing.com/problem/content/description/234/ 题意:有n次挑战,每次挑战获胜可以得到一个地图碎片值为-1 或者 可以得到一个 ...
- HDU 1828 线段树+扫描线(计算矩形周长并)
题意:给你n个矩形,然后矩形有可能重叠,要你求周长 思路:首先碰到这种矩形在数轴上那么第一反应应该想到的是扫描线, 做周长我们有两种方法 第一种,我们可以分开两部分求,第一遍求x轴上的贡献,第二遍求y ...
- AcWing 215. 破译密码 (莫比乌斯反演)打卡
达达正在破解一段密码,他需要回答很多类似的问题: 对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d. 作为达达的同学,达达希望得到你的帮助. ...
- 关于Burp Suite不能抓包的解决方法
一.Burp Suite有时能抓到包,有时不能抓到包 解决方法: 出现这种问题的原因就是代理没有设置成全局的,只是设置成了局部的. 打开IE浏览器,依次打开工具->Internet 属性-> ...
- 耗时十个月的德国APS,教会我的学习方法
考过了准备了10个月的Aps ,想送给关注我的8175个粉丝,一份礼物,感谢你们看的起我,对我的支持和关注. 这份礼物,我就大言不惭的称之为:达令的学习方法. 我的考试经历:高考两次,中戏艺考三试,导 ...
- 浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变【转】
浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变 前言:2009年10月23日,微软高调发布了其最新一代操作系统——Windows7,这款操作系统相对于 ...
- js匿名函数测试
js匿名函数测试 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...
- eclipse 集成 STS 插件
eclipse 集成 STS 插件 想新建一个 Spring Boot 工程,发现没有,如图:(展示的是集成之后的) eclipse 要和 sts 版本对应的,进入http://spring.io/t ...
- kafka安装指导
本篇博客主要讲解在虚拟机安装之后,从如下五个方面进行讲解kafka的安装过程. (1)如何配置虚拟机网络 (2)如何安装JDK (3)如何安装zookeeper (4)如何安装kafka (5)kaf ...
- vue - blog开发学习2
首页博客列表的开发 1.修改index.vue,使能够支持列表功能 <template> <div> <PostList v-for="(item,index) ...