zoukankan      html  css  js  c++  java
  • 旅行商问题 (状压dp入门)

    题面

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

    输入格式
    第一行输入整数n。

    接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(记为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]。

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

    数据范围
    1≤n≤20
    0≤a[i,j]≤107
    输入样例:
    5
    0 2 4 5 1
    2 0 6 5 3
    4 6 0 8 3
    5 5 8 0 5
    1 3 3 5 0
    输出样例:
    18

    思路

    状压dp的入门题目,本题数据量是二十,哈密顿周游问题是一个np完全问题,所以我们可以暴力解,那么暴力枚举复杂度20的阶乘,大概在18次方左右,显然我们不能接受。所以我们需要考虑状态压缩。首先我们想,我们有四个点,1234,我们要从1走到4,两种走法,1->2->3>4和1->3->2->4,我们假设第一种走法距离为2,第二种走法,距离为3,那么,在后续的路程中,如果前半段是这样的一个走法,后半段的每一个走法,这两个方案都会一一对应,然而第一个方案总比第二个小1,所以我们不需要枚举第二种方案就可以取得最优值,这就是dp的思想。那么,我们如何枚举哪,基于上面的论述,我们所需要的的条件就是我们的终点和我们所走过的点,那么我们走过的点怎么枚举呢,这就要用到二进制数来进行一个状态的压缩了。我们一共的状态就是1<<20个,然后进行一个状态的转移就好了。当然我们在枚举的时候可以进行一个剪枝,就是我们要去掉目前的终点枚举上一个状态的时候,我们可以判断一下,这个终点是否在我上层循环的状态里面,后面也是一样。

    代码实现

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int M=1<<20;
    const int N=20;
    int f[M][N],maze[N][N];
    int n;
    int main () {
        cin>>n;
        for (int i=0;i<n;i++)
         for (int j=0;j<n;j++) cin>>maze[i][j];
        memset (f,0x3f3f3f3f,sizeof (f));
        f[1][0]=0;
        for (int i=0;i<1<<n;i++) 
         for (int j=0;j<n;j++)
          if (i>>j&1) {
              for (int k=0;k<n;k++) {
                  if (i-(1<<j)>>k&1) {
                      f[i][j]=min (f[i][j],f[i-(1<<j)][k]+maze[k][j]);
                  }
              }
          }
        cout<<f[(1<<n)-1][n-1]<<endl;
        return 0;
    }
    
  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/hhlya/p/13305987.html
Copyright © 2011-2022 走看看