zoukankan      html  css  js  c++  java
  • HDU 3001 Travelling(状态压缩DP+三进制)

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

    题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上,要求经过所有城市并且花费最少,求出最小花费。

    解题思路:三进制的状态压缩DP,跟二进制还是有一点不一样的,因为三进制没有直接的位运算,还要自己先做处理利用num[i][j]记录数字i各位的三进制表示方便计算,其他的就跟二进制状态压缩没有太大区别了。还有注意:

         ①开始要将n个起点初始化,dp[bit[i]][i]=0

         ②有重边,要去重

    代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<queue>
     5 #include<cstring>
     6 using namespace std;
     7 const int INF=0x3f3f3f3f;
     8 const int N=6e4+5;
     9 
    10 int n,m,ans;
    11 int map[15][15];
    12 int dp[N][15];
    13 int bit[15]={1,3,9,27,81,243,729,2187,6561,19683,59049};
    14 int num[N][15];
    15 
    16 //计算所有数字10位以内三进制表示 
    17 void make_tab(){
    18     for(int i=0;i<bit[10];i++){
    19         int b=i;
    20         for(int j=0;j<10;j++){
    21             num[i][j]=b%3;
    22             b/=3;
    23         }
    24     }
    25 }
    26 
    27 int main(){
    28     make_tab(); 
    29     while(~scanf("%d%d",&n,&m)){
    30         memset(map,0x3f,sizeof(map));
    31         memset(dp,0x3f,sizeof(dp));
    32         int ans=INF; 
    33         for(int i=1;i<=m;i++){
    34             int a,b,c;
    35             scanf("%d%d%d",&a,&b,&c);
    36             a--,b--;
    37             //去重边 
    38             map[a][b]=min(map[a][b],c);
    39             map[b][a]=min(map[b][a],c);
    40         }
    41         for(int i=0;i<n;i++)
    42             dp[bit[i]][i]=0;//对每个点定位初始点0
    43         
    44         for(int i=0;i<bit[n];i++){
    45             bool flag=true;//表示所有位都是>=1,也就是每个城镇都走过了 
    46             for(int j=0;j<n;j++){
    47                 if(num[i][j]==0)
    48                     flag=false;
    49                 if(dp[i][j]==INF)//判断是否走到j点 
    50                     continue;
    51                 for(int k=0;k<n;k++){
    52                     //注意这个num[i][k]>=2,因为如果i状态在k点已经走过两次了显然是不能继续往下走的 
    53                     if(j==k||num[i][k]>=2||map[j][k]==INF)
    54                         continue;
    55                     int next=i+bit[k];//从j点走到k点 
    56                     dp[next][k]=min(dp[next][k],dp[i][j]+map[j][k]); 
    57                 } 
    58             }
    59             //如果所有城镇都走了一遍则可以找出最小值 
    60             if(flag){
    61                 for(int j=0;j<n;j++)
    62                     ans=min(ans,dp[i][j]);
    63             }
    64         }
    65         if(ans==INF)
    66             puts("-1");
    67         else
    68             printf("%d
    ",ans);
    69     }    
    70     return 0;
    71 } 
  • 相关阅读:
    FastDFS 与 Nginx 实现分布式图片服务器
    git(三) 使用github
    html表单笔记
    Jquery笔记和ajax笔记
    CSS笔记
    javascript笔记
    idea笔记
    spring boot 框架设计步骤
    spring boot启动项的问题
    Loading class `com.mysql.jdbc.Driver'. The new driver class is `com.mysql.cj.jdb 问题
  • 原文地址:https://www.cnblogs.com/fu3638/p/7580916.html
Copyright © 2011-2022 走看看