zoukankan      html  css  js  c++  java
  • 状态压缩 之 UVA 10944

    //  [9/19/2014 Sjm]
    /*
    dis[j][k] := 从 j 点到 k 点的最少步数,由于They can travel in all 8 adjacent direction in one step.
                 故而 dis[j][k] = max( abs(Xj - Xk), abs(Yj - Yk) )
     
    f[j][i] := 在 i 状态下,最后收集坚果 j 的最少步数
     
    n 代表坚果的数目。。
     
    阶段i:按递增顺序枚举状态值 (0 <= i <= 2^n - 1)
    状态 :枚举状态 i 中最后被收集的坚果 j (1 <= j <= n, i&(2^(j-1)) != 0)
    决策 :枚举状态 i 以外的坚果 k(1 <= k <= n, i&(2^(k-1)) == 0) ,
           判断在状态 i,最后被收集的坚果为j的情况下,再收集坚果 k ,是否为最优决策。
           即: f[k][i+2^(k-1)] = min(f[k][i+2^(k-1)], f[j][i] + dis[j][k])
     
    求最终解:
    枚举 f[j][2^n - 1] + dis[j][0] (1 <= j <= n),
    */
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #define INF 0x3f3f3f3f
     6 using namespace std;
     7 int n, dis[20][20], myX, myY, f[20][(1 << 20)];
     8 
     9 struct myNode {
    10     int x, y;
    11 }node[20];
    12 
    13 void Init(int i, char str[])
    14 {
    15     for (int j = 0; j < myY; ++j){
    16         if ('#' == str[j]) {
    17             node[++n].x = i;
    18             node[n].y = j;
    19         }
    20         else if ('L' == str[j]) {
    21             node[0].x = i;
    22             node[0].y = j;
    23         }
    24     }
    25 }
    26 
    27 void getDis() {
    28     for (int i = 0; i <= n; ++i) {
    29         for (int j = 0; j <= n; ++j) {
    30             dis[i][j] = max(abs(node[i].x - node[j].x), abs(node[i].y - node[j].y));
    31         }
    32     }
    33 }
    34 
    35 void Solve() {
    36     int finalState = (1 << n) - 1;
    37     for (int j = 1; j <= n; ++j) {
    38         for (int i = 0; i <= finalState; ++i) {
    39             f[j][i] = INF;
    40         }
    41     }
    42     for (int j = 1; j <= n; ++j) {
    43         f[j][1 << (j - 1)] = dis[0][j];
    44     }
    45     for (int i = 0; i < finalState; ++i) {
    46         for (int j = 1; j <= n; ++j) {
    47             if (i & (1 << (j - 1))) {
    48                 for (int k = 1; k <= n; ++k) {
    49                     if (!(i & (1 << (k - 1)))) {
    50                         f[k][i + (1 << (k - 1))] = min(f[k][i + (1 << (k - 1))], f[j][i] + dis[j][k]);
    51                     }
    52                 }
    53             }
    54         }
    55     }
    56     int ans = INF;
    57     for (int j = 1; j <= n; ++j) {
    58         ans = min(ans, f[j][finalState] + dis[j][0]);
    59     }
    60     printf("%d
    ", ans);
    61 }
    62 
    63 int main()
    64 {
    65     while (~scanf("%d %d", &myX, &myY)) {
    66         char str[25];
    67         n = 0;
    68         for (int i = 0; i < myX; ++i) {
    69             scanf("%s", str);
    70             Init(i, str);
    71         }
    72         if (0 == n) {   // 注意无坚果的情况。。
    73             printf("0
    ");
    74             continue;
    75         }
    76         getDis();
    77         Solve();
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    leetcode 43. 字符串相乘
    leetcode 20. 有效的括号 (python)
    leetcode 125. 验证回文串(python)
    leetcode 171. Excel表列序号(python)
    leetcode 190. 颠倒二进制位(c++)
    leetcode 122. 买卖股票的最佳时机 II (python)
    leetcode 118. 杨辉三角(python)
    leetcode 141. 环形链表(C++)
    leetcode 189. 旋转数组(python)
    leetcode 217. 存在重复元素 (python)
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140800.html
Copyright © 2011-2022 走看看