题目链接: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 }