zoukankan      html  css  js  c++  java
  • HDU 5067 Harry And Dig Machine:TSP(旅行商)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5067

    题意:

      给你一个n*m的地图,地图上标着对应位置的石子数。你从左上角出发,每次可以向上下左右四个方向移动。你要遍历所有有石子的地方,并返回起点。问你最少的移动步数。

    题解:

      简化问题:

        只保留起点和有石子的点,预处理出保留点两两之间的最短路(曼哈顿距离),将矩阵转化为一个无向图。

        原题变为了TSP模板题。

      然后套模板就好了。。。

      三重for循环,分别枚举state、当前位置i、下一步位置j。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <math.h>
     5 #define MAX_N 55
     6 #define MAX_S (1<<15)
     7 #define INF 10000000
     8 
     9 using namespace std;
    10 
    11 int n,m;
    12 int cnt;
    13 int ans;
    14 int x[MAX_N];
    15 int y[MAX_N];
    16 int dis[MAX_N][MAX_N];
    17 int dp[MAX_S][MAX_N];
    18 
    19 void read()
    20 {
    21     cnt=0;
    22     int temp;
    23     for(int i=0;i<n;i++)
    24     {
    25         for(int j=0;j<m;j++)
    26         {
    27             cin>>temp;
    28             if(temp>0 || (i==0 && j==0))
    29             {
    30                 x[cnt]=i;
    31                 y[cnt]=j;
    32                 cnt++;
    33             }
    34         }
    35     }
    36 }
    37 
    38 void cal_dis()
    39 {
    40     for(int i=0;i<cnt;i++)
    41     {
    42         for(int j=0;j<cnt;j++)
    43         {
    44             dis[i][j]=fabs(x[i]-x[j])+fabs(y[i]-y[j]);
    45         }
    46     }
    47 }
    48 
    49 void solve()
    50 {
    51     cal_dis();
    52     memset(dp,-1,sizeof(dp));
    53     dp[0][0]=0;
    54     for(int state=0;state<(1<<cnt);state++)
    55     {
    56         for(int i=0;i<cnt;i++)
    57         {
    58             if(dp[state][i]!=-1)
    59             {
    60                 for(int j=0;j<cnt;j++)
    61                 {
    62                     if( !((state>>j)&1) && (dp[state|(1<<j)][j]==-1 || dp[state|(1<<j)][j]>dp[state][i]+dis[i][j]) )
    63                     {
    64                         dp[state|(1<<j)][j]=dp[state][i]+dis[i][j];
    65                     }
    66                 }
    67             }
    68         }
    69     }
    70     ans=INF;
    71     for(int i=0;i<cnt;i++)
    72     {
    73         if(dp[(1<<cnt)-1][i]!=-1) ans=min(ans,dp[(1<<cnt)-1][i]+dis[i][0]);
    74     }
    75 }
    76 
    77 void print()
    78 {
    79     cout<<ans<<endl;
    80 }
    81 
    82 int main()
    83 {
    84     while(cin>>n>>m)
    85     {
    86         read();
    87         solve();
    88         print();
    89     }
    90 }
  • 相关阅读:
    Ubuntu oracle SDK替换OpenJDK
    用update-alternatives管理java版本
    安卓配置
    CS 159: Advanced Topics in Machine Learning: Structured Prediction
    ros bag 代码操作
    vim 方式快捷编辑代码
    文件权限
    操作系统连不上网
    github权限管理
    nmap基本命令使用
  • 原文地址:https://www.cnblogs.com/Leohh/p/7368551.html
Copyright © 2011-2022 走看看