alwaysBeAStarter

博客园 首页 新随笔 联系 订阅 管理

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=21&page=show_problem&problem=1885

Dynamic Programming. dp[i][j]表示以ith nut为结尾,状态j下的最少步数。假设有n个nuts,状态有(2^(n-1))-1个。一步一步的添加得到最后结果。代码如下:

  1 #include <iostream>
  2 #include <math.h>
  3 #include <stdio.h>
  4 #include <cstdio>
  5 #include <algorithm>
  6 #include <string.h>
  7 #include <string>
  8 #include <sstream>
  9 #include <cstring>
 10 #include <queue>
 11 #include <vector>
 12 #include <functional>
 13 #include <cmath>
 14 #include <set>
 15 #define SCF(a) scanf("%d", &a)
 16 #define IN(a) cin>>a
 17 #define FOR(i, a, b) for(int i=a;i<b;i++)
 18 #define Infinity 999999999
 19 typedef long long Int;
 20 using namespace std;
 21 
 22 struct point {
 23     int x, y;
 24 };
 25 
 26 int x, y;
 27 point nuts[16];
 28 int num = 0;
 29 int dp[16][65536];
 30 int dis[16][16];
 31 
 32 int main()
 33 {
 34     while (scanf("%d %d", &x, &y) != EOF)
 35     {
 36         num = 1;
 37         getchar();
 38         FOR(i, 0, x)
 39         {
 40             FOR(j, 0, y)
 41             {
 42                 char c = getchar();
 43                 if (c == 'L')
 44                 {
 45                     nuts[0].x = i;
 46                     nuts[0].y = j;
 47                 }
 48                 else if (c == '#')
 49                 {
 50                     nuts[num].x = i;
 51                     nuts[num++].y = j;
 52                 }
 53             }
 54             getchar();
 55         }
 56 
 57         if (num == 1)
 58         {
 59             printf("%d\n", 0);
 60             continue;
 61         }
 62 
 63         FOR(i, 0, num)
 64         {
 65             FOR(j, i, num)
 66             {
 67                 dis[i][j] = dis[j][i] = max(abs(nuts[i].x - nuts[j].x), abs(nuts[i].y - nuts[j].y));
 68             }
 69         }
 70 
 71         int states = (1 << (num - 1)) - 1;
 72         for (int s = 0; s <= states; s++)
 73         {
 74             for (int i = 1; i < num; i++)
 75             {
 76                 dp[i][s] = Infinity;
 77             }
 78         }
 79 
 80         for (int i = 1; i < num; i++)
 81             dp[i][1 << (i - 1)] = dis[0][i];
 82 
 83         for (int i = 1; i <= states; i++)
 84         {
 85             for (int j = 1; j < num; j++)
 86             {
 87                 if (i & (1 << (j - 1)))
 88                 {
 89                     for (int k = 1; k < num; k++)
 90                     {
 91                         if (!(i & (1 << (k - 1))))
 92                         {
 93                             if (dp[k][i + (1 << (k - 1))] > dp[j][i] + dis[j][k])
 94                                 dp[k][i + (1 << (k - 1))] = dp[j][i] + dis[j][k];
 95                         }
 96                     }
 97                 }
 98             }
 99         }
100         int finalAns = Infinity;
101         for (int i = 1; i < num; i++)
102         {
103             if (dp[i][states] + dis[i][0] < finalAns)
104                 finalAns = dp[i][states] + dis[i][0];
105         }
106         printf("%d\n", finalAns);
107 
108     }
109     return 0;
110 }

 

posted on 2017-06-22 22:17  alwaysBeAStarter  阅读(101)  评论(0编辑  收藏  举报