zoukankan      html  css  js  c++  java
  • HDU 3001 Travelling 状态DP

    TSP问题,不懂就是每个点最多访问两次,最少访问一次。

    所以,我们可以用三进制来当做状态。

    这个题练习了一下三进制……0、1、2

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <string>
     8 #include <queue>
     9 #include <stack>
    10 #include <vector>
    11 #include <map>
    12 #include <set>
    13 #include <functional>
    14 #include <time.h>
    15 
    16 using namespace std;
    17 
    18 const int INF = 1<<30;
    19 
    20 int Matrix[15][15];
    21 int base[70000][15]; //base[i][j]表示 数字i从右边第j位起的三进制值
    22 int dp[70000][15];
    23 int thr[20];
    24 int n, m;
    25 
    26 inline bool check(int x) { //判断是否是最终状态
    27     for (int i = 0; i < n; i++) if (!base[x][i]) //如果某一位是0则不是
    28         return false;
    29     return true;
    30 }
    31 
    32 inline void update(int st, int u, int v) { //更新状态
    33     int &now = dp[st+thr[v]][v];
    34     if (now<0) now = dp[st][u]+Matrix[u][v];
    35     else now = min(now, dp[st][u]+Matrix[u][v]);
    36 }
    37 
    38 void init() {
    39     thr[0] = 1;
    40     for (int i = 1; i < 20; i++)
    41         thr[i] = thr[i-1]*3;
    42     for (int i = 0; i < 70000; i++) {
    43         int j = i, k = 0;
    44         while (j) {
    45             base[i][k++] = j%3;
    46             j /= 3;
    47         }
    48     }
    49 }
    50 
    51 void input() {
    52     memset(Matrix, -1, sizeof(Matrix));
    53     for (int i = 0; i < m; i++) {
    54         int x, y, c;
    55         scanf("%d%d%d", &x, &y, &c);
    56         x--; y--;
    57         if (-1==Matrix[x][y]) Matrix[x][y] = Matrix[y][x] = c;
    58         else Matrix[x][y] = Matrix[y][x] = min(Matrix[x][y], c);
    59     }
    60 }
    61 
    62 void solve() {
    63     memset(dp, -1, sizeof(dp));
    64     for (int i = 0; i < n; i++)
    65         dp[thr[i]][i] = 0;
    66     for (int i = 1; i < thr[n]; i++) {
    67         for (int u = 0; u < n; u++) if (dp[i][u]>-1) { //此状态可达
    68             for (int v = 0; v < n; v++) if (u!=v && base[i][v]<2 && Matrix[u][v]>-1){ //可以转移到下一个状态
    69                 update(i, u, v); //更新下一个状态
    70             }
    71         }
    72     }
    73 
    74     int ans = -1;
    75     for (int i = 0; i < thr[n]; i++) if (check(i)) {
    76         for (int j = 0; j < n; j++) if (-1 < dp[i][j]) {
    77             ans = ans>-1 ? min(ans, dp[i][j]) : dp[i][j];
    78         }
    79     }
    80     printf("%d
    ", ans);
    81 }
    82 
    83 int main() {
    84     #ifdef Phantom01
    85         freopen("HDU3001.txt", "r", stdin);
    86     #endif //Phanaom01
    87 
    88     init();
    89     while (scanf("%d%d", &n, &m)!=EOF) {
    90         input();
    91         solve();
    92     }
    93 
    94     return 0;
    95 }
    HDU3001
  • 相关阅读:
    再谈CLR:值类型按照引用传递(以及与装箱拆箱的区别)
    Silverlight的跨站策略和跨站策略文件
    再谈CLR:MSCorEE.dll文件的奥秘
    再谈CLR:如何通过代码获取程序集所引用的程序集信息
    再谈方法的动态调用
    Silverlight隔离存储(续)
    支持取消操作和暂停操作的Backgroundworker
    单件模式(Singleton)和锁定(lock)
    在SharePoint服务器中执行备份和还原
    如何:将 TraceSource 和筛选器与跟踪侦听器一起使用(转载)
  • 原文地址:https://www.cnblogs.com/Phantom01/p/3710606.html
Copyright © 2011-2022 走看看