博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
『最短Hamilton路径 状态压缩DP』
阅读量:6238 次
发布时间:2019-06-22

本文共 1083 字,大约阅读时间需要 3 分钟。

状压DP入门


最短Hamilton路径

Description

给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。

Input Format

第一行一个整数n。 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j])。 对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]>=a[x,z]。

Output Format

一个整数,表示最短Hamilton路径的长度。

Sample Input

40 2 1 32 0 2 11 2 0 13 1 1 0

Sample Output

4

解析

很容易想到的朴素解法是枚举全排列,时间复杂度\(O(n*!n)\),显然是会\(TLE\)的。注意到\(n<20\),我们考虑状态压缩\(DP\)。设\(f[i][S]\)代表当前遍历状态为\(S\),到了第\(i\)个点的最短长度。如何理解遍历状态\(S\)呢?我们把它当做一个二进制的\(01\)串,从右数第i位为如果为\(0\),就说明节点i没有被遍历到过,如果第\(i\)位为\(1\),则说明节点i被遍历到过了。我们将整个图的遍历状态记为一个二进制数,这就是状态压缩。

那么我们考虑如何\(DP\)。我们将编号记为从\(1\)开始的,那么初始状态就是\(f[1][1]=0\)

这里我们需要先理解状态的查询和赋值操作:

1.S&(1<<(i-1))代表取出状态S的(从右往左)第i位

2.S|(1<<(i-1))代表将状态S的(从右往左)第i位赋值为1

那么我们就可以得到状态转移方程了:\[f[j][S|(1<<(j-1))]=\min\{f[i][S]+dis[i][j]\}\]

需要满足节点\(j\)未访问,节点\(i\)已经访问过了。

状态的初值一开始均为正无穷,枚举\(S,i,j\)即可转移,时间复杂度\(O(n^2*2^n)\),目标状态为\(f[n][(1<<n)-1]\)

\(Code:\)

#include
using namespace std;const int N=20;int n,dis[N+5][N+5],f[N+5][(1<


转载于:https://www.cnblogs.com/Parsnip/p/10357907.html

你可能感兴趣的文章
10个php中的$_SERVER函数
查看>>
美团实时计算平台实践与应用
查看>>
[翻译-Shiro]-10分钟教会你Apache Shiro
查看>>
糗事百科客户端
查看>>
ZUUIRevealController
查看>>
开源 java CMS - FreeCMS2.0发布。
查看>>
android handler 如何规避内存泄漏
查看>>
使用K个数字(< 10)组成和为N的组合
查看>>
python good link
查看>>
关于SQL的
查看>>
Ubuntu下安装yii
查看>>
[Android]让RemoteControlClient显示Music Album
查看>>
01-UI基础-03UIImageView
查看>>
JSP页面ajax提交登录数据demo
查看>>
软件自动化测试框架STAF
查看>>
Hadoop 多表连接
查看>>
使用maven下载jar包,使用ant打包。yqxt项目的安装。
查看>>
Ubuntu 一键安装openresty
查看>>
dlmalloc
查看>>
学习与准备的一些资源
查看>>