Traveling Salesman Problem

  Description:                    Time Limit: 4sec    Memory Limit:256MB

  有编号1到N的N个城市,问从1号城市出发,遍历完所有的城市并最后停留在N号城市的最短路径长度。

  Input:

  第一行整数 T :T组数据 (T<=20) 

  每个case 读入一个N( 2 <= N <= 20),接着输入N行,第i行有两个整数 xi , yi 表示第 i 个城市坐标轴上的坐标 。

  Output:

  每个case输出一个浮点数表示最短路径。四舍五入保留两位小数。

  Sample Input:

  1 4 0 0 1 0 1 1 0 1

  Sample Output:

  3.41

  经典难题!数据开到这么小就知道没有那么简单的复杂度了,一般的算法,即爆搜,复杂度为 o( n! ) ,我们这里采用的动态规划算法,

  算法复杂度已经从阶乘级降到了o( ( n^2 )*( 2^n ) ) (看起来也是相当恐怖的,不过像这种经典难题这种复杂度对我来说已经不错了)。

  开始说说思路,一开始马上想到的必然是搜索,搜索必然超时,于是某大神直接告诉我——记忆化搜索,记忆化搜索能做的动规就能做,写递归太麻烦了于是动规!

  题目中起点终点确定,我们可以考虑用一个二维dp数组来保存一个状态——dp[i]{V}表示从结点0到结点 i 途经V中所有节点的最短路径长(这里的V是一个集合)

  于是状态转移方程可以为:dp[i]{V}=min( dp[i]{V} , dist[i][j]+dp[j]{V-{j}} )  (j 属于 V)

  

  大思路定好了,我们来考虑细节部分,主要有以下部分:

  1)建图等等:结构体point,距离函数dist;

  2)集合V的表示:二进制数,即010表示三个数的集合第二个有,其余无;

  3)dp过程的范围:1 ~ n-1 (最大可能为 1 ~ 18 );

  

  于是我们可以敲代码啦!

#include <bits/stdc++.h>
const double INF=10e7; using namespace std; int T,n,cnt;
double a[25][25],dp[25][1100000]; struct point{ //结点结构体
int x,y;
}pt[25]; double d(point a,point b){ //结点间距离
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} int main()
{
scanf("%d",&T);
while(T--)
{
cnt=1;
scanf("%d",&n);
for(int i=2;i<n;i++) cnt<<=1; //组合数(除起点终点外) for(int i=0;i<n;i++) //输入
scanf("%d %d",&pt[i].x,&pt[i].y); for(int i=0;i<n;i++) //建边
for(int j=0;j<n;j++)
a[i][j]=d(pt[i],pt[j]); for(int i=0;i<n;i++) //初始化
for(int j=0;j<cnt;j++)
dp[i][j]=INF; for(int i=0;i<n;i++) //起点确定,定下初始条件
dp[i][0]=a[i][0];
for(int i=1;i<cnt;i++) //从有元素考虑起
for(int j=1;j<n-1;j++)
{
for(int k=1;k<n-1;k++)
{
if((1<<k-1)&i) //k is in the set
dp[j][i]=min(dp[j][i],a[j][k]+dp[k][i-(1<<k-1)]); //状态转移方程
}
}
double ans=INF;
for(int i=1;i<n;i++)
ans=min(ans,dp[i][cnt-1]+a[i][n-1]); printf("%.2lf\n",ans);
} return 0;
}

  之前动态规划也是做了不少的基础例题,这道题算是动态规划的第一次成功应用,还是蛮开心的,软创得加油啊!

  

TSP问题——动态规划的更多相关文章

  1. UVA116-Unidirectional TSP(动态规划基础)

    Problem UVA116-Unidirectional TSP Accept: 7167  Submit: 56893Time Limit: 3000 mSec Problem Descripti ...

  2. uva 116 Unidirectional TSP(动态规划,多段图上的最短路)

    这道题目并不是很难理解,题目大意就是求从第一列到最后一列的一个字典序最小的最短路,要求不仅输出最短路长度,还要输出字典序最小的路径. 这道题可以利用动态规划求解.状态定义为: cost[i][j] = ...

  3. TSP问题[动态规划]

    分析: 有用的量:城市集合V={a,b,c,d,--} 所以我们用 T(i,V) 表示从 城市 i 出发遍历集合 V 中的城市一遍且仅一遍后回到 i 所用的最少费用(这里可能表达不好,底下会看到,但是 ...

  4. TSP(旅行者问题)——动态规划详解(转)

    1.问题定义 TSP问题(旅行商问题)是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短. 假设现在有四个城市,0,1,2,3,他们之间的代价如图一,可以存成 ...

  5. 多线程动态规划算法求解TSP(Traveling Salesman Problem) 并附C语言实现例程

    TSP问题描述: 旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人要拜访n个城市,他必须 ...

  6. TSP(Traveling Salesman Problem)-----浅谈旅行商问题(动态规划,回溯实现)

    1.什么是TSP问题 一个售货员必须访问n个城市,这n个城市是一个完全图,售货员需要恰好访问所有城市的一次,并且回到最终的城市. 城市于城市之间有一个旅行费用,售货员希望旅行费用之和最少. 完全图:完 ...

  7. POJ 3311 Hie with the Pie 兼 Codevs 2800 送外卖(动态规划->TSP问题)

    Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possi ...

  8. 动态规划-TSP问题-最短超级串

    2020-03-03 22:55:08 问题描述: 给定一个字符串数组 A,找到以 A 中每个字符串作为子字符串的最短字符串. 我们可以假设 A 中没有字符串是 A 中另一个字符串的子字符串. 示例 ...

  9. uva 116 - Unidirectional TSP (动态规划)

    第一次做动规题目,下面均为个人理解以及个人方法,状态转移方程以及状态的定义也是依据个人理解.请过路大神不吝赐教. 状态:每一列的每个数[ i ][ j ]都是一个状态: 然后定义状态[ i ][ j ...

随机推荐

  1. Nginx去除版本号

    1.在配置文件中的 http节点中加入server_tokens off; 2.更改源码隐藏nginx软件的名称 1). 查看Nginx编译的参数/usr/local/nginx/sbin/nginx ...

  2. TEX学习笔记

    整理在这里, 方便以后容易查找. 毕竟每个tex的模板有些不一样. Beamer: Latex beamer 学习总结 http://blog.sina.com.cn/s/blog_6cf921f30 ...

  3. 《前端们,贺老 Live 面试你了!》所引发的思考与实践

    贺老在知乎live中提到了一个这样的问题: 产品经理提出了一个需求:用户点击文章阅读,返回之后阅读其他文章.当用户看得多了,容易点到自己看过的文章,造成时间浪费.所以想给点击过的文章加一个标记,如:& ...

  4. bootstrap下使用模态框,在模态框内输入框中回车时,模态框自动关闭的问题及解决方法

    使用bootstrap下模态框,构建表单提交页面,但是输入框中直接回车,本来是想执行一下验证,但是却导致模态框自动关闭了. 遇到这样的问题,只需要先禁止回车触发表单提交            $(do ...

  5. QTP参数化

    使用QTP可以通过将固定值替换为参数,扩展测试范围,可以提高测试的灵活性. 在QTP中,我们可以对以下部分进行参数化: 1.对象属性参数化 2.对象名称的参数化 3.对象方法的参数的参数化

  6. XML文档

    XML(Extensible Markuo Language)可标记扩展语言.它是一种以简单文本格式存储数据的方式,可以被任何计算机读取. XML文档里包含的元素都是可以自定义的. 1.XML文档声明 ...

  7. python2.7.9基础学习

     一.  基 础 python python开头两行注释代码意义:         #!/usr/bin/python 是用来说明脚本语言是python的,是要用/usr/bin下面的程序(工具)py ...

  8. IOS开发者账号申请记录

    1. 准备好一个企业邮箱 .企业营业执照复印件.一张可以支付的VISA或者MasterCard 2. 2016/01/13 注册appid https://developer.apple.com/pr ...

  9. Thinkphp源码分析系列(五)–系统钩子实现

    Thinkphp的插件机制主要依靠的是Hook.class.php这个类,官方文档中在行为扩展也主要依靠这个类来实现.下面我们来具体看看tp是怎么利用这个类来实现行为扩展的. 首先,行为扩展是什么?有 ...

  10. Tomcat回收连接

    最近公司一个JDK1.4的老项目升级了JDK1.6后BUG不断,最可恶的连接池被占满. 因为是使用tomcat的连接池所以在config下中添加 <Resource name="jdb ...