zoukankan      html  css  js  c++  java
  • sss

    <更新提示>

    <第一次更新>状压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

    4
    0 2 1 3
    2 0 2 1
    1 2 0 1
    3 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<bits/stdc++.h>
    using namespace std;
    const int N=20;
    int n,dis[N+5][N+5],f[N+5][(1<<N)+5],ans=0x3f3f3f3f;
    inline void input(void)
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			scanf("%d",&dis[i][j]);
    }
    inline void dp(void)
    { 
    	memset(f,0x3f,sizeof f);
    	f[1][1]=0;
    	for(int S=1;S<(1<<n);S++)
    		for(int i=1;i<=n;i++)
    			if(S&(1<<(i-1)))
    				for(int j=1;j<=n;j++)
    					if( not (S&(1<<(j-1))) )
    						f[j][S|(1<<(j-1))]=min(f[j][S|(1<<(j-1))],f[i][S]+dis[i][j]);
    
    }
    int main(void)
    {
    	freopen("test.in","r",stdin);
    	freopen("test.out","w",stdout);
    	input();
    	dp();
    	printf("%d
    ",f[n][(1<<n)-1]);
    }
    
    

    <后记>

  • 相关阅读:
    flutter PageView实现左右滑动切换视图
    Flutter进阶:在应用中实现 Hero(飞行) 动画
    阿里云申请免费SSL证书,并配置到Tomcat,实现https访问
    Tomcat 部署项目的三种方法
    idea jsp文件中body标签内引入编辑器后提示statement expected
    UEditor设置内容setContent()失效的解决方法
    UEditor API
    easyui-dialog打开之后append("标签")标签存在但是显示不出来
    combogrid下拉方法封装
    java中try 与catch的使用
  • 原文地址:https://www.cnblogs.com/Parsnip/p/10357907.html
Copyright © 2011-2022 走看看