并没有做过这种类型的题目,不太会做...看了一下大神的代码,然后自己敲...额..思路一样了,代码也差不多..
http://www.cnblogs.com/kuangbin/archive/2012/08/14/2637512.html
先通过BFS预处理任意两点之间的距离,然后通过DFS暴力模拟路径,算出最优解.
感觉自己可能对BFS理解比DFS更深一点,或者说,BFS比较简单一点吧...
这题还有一种解法是状态压缩+BFS...通过开设一个int型变量记录是否拿到宝物,然后暴力..不过这种方法一不小心就超时了..需要注意一些优化的细节;
例如: 0000000000 | 0000000001 ,这样就拿到第一个宝箱...解法和HDU 1429 是相似的.
1 #include <iostream> 2 #include <string.h> 3 #include <queue> 4 #define MAXN 55 5 int T, H, W, L, M,Sum,ans,Case; 6 int dir[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 }; 7 int dis[12][12]; 8 int value[12]; 9 bool visit_bfs[MAXN][MAXN]; 10 bool visit_dfs[MAXN]; 11 char map[MAXN][MAXN]; 12 struct node{ 13 int x, y; 14 int step; 15 }; 16 using namespace std; 17 bool check(int x, int y) 18 { 19 if (x<0 || x>=W || y<0 || y>=H || map[x][y] == '*') 20 return false; 21 return true; 22 } 23 int bfs(int x,int y,int begin) 24 { 25 node cur, next; 26 queue<node> game; 27 memset(visit_bfs, false, sizeof(visit_bfs)); 28 cur.x = x, cur.y = y, cur.step = 0; 29 visit_bfs[x][y] = true; 30 game.push(cur); 31 while (!game.empty()) 32 { 33 cur = game.front(); 34 game.pop(); 35 for (int i = 0; i < 4; i++) 36 { 37 next.x = cur.x + dir[i][0]; 38 next.y = cur.y + dir[i][1]; 39 if (!check(next.x, next.y) || visit_bfs[next.x][next.y]) 40 continue; 41 // cout << next.x << " " << next.y << endl; 42 visit_bfs[next.x][next.y] = true; 43 next.step = cur.step + 1; 44 if (map[next.x][next.y] == '@'){ 45 dis[begin][0] = next.step; 46 } 47 else if (map[next.x][next.y] == '<'){ 48 dis[begin][M+1] = next.step; 49 } 50 else if (map[next.x][next.y] >= 'A' && map[next.x][next.y] <= 'Z') 51 { 52 dis[begin][map[next.x][next.y] - 'A' + 1] = next.step; 53 } 54 game.push(next); 55 } 56 } 57 return 0; 58 } 59 void dfs(int cur,int score,int time) 60 { 61 if (ans == Sum) 62 return; 63 if (time > L) 64 return; 65 if (cur > M){ 66 if (score > ans) 67 ans = score; 68 } 69 for (int i = 0; i <= M+1; i++) 70 { 71 if (!visit_dfs[i]&&dis[cur][i]){ 72 visit_dfs[i] = true; 73 dfs(i, score + value[i], time + dis[cur][i]); 74 visit_dfs[i] = false; 75 } 76 } 77 } 78 int main() 79 { 80 //freopen("test.txt", "r", stdin); 81 Case = 1; 82 scanf("%d", &T); 83 while (T--) 84 { 85 scanf("%d%d%d%d", &H, &W, &L, &M); 86 Sum = 0; 87 for (int i = 1; i <= M; i++){ 88 scanf("%d", value + i); 89 Sum += value[i]; 90 } 91 value[0] = value[M+1] = 0; 92 memset(visit_dfs, false, sizeof(visit_dfs)); 93 memset(dis, 0, sizeof(dis)); 94 for (int i = 0; i < W; i++) 95 scanf("%s", map + i); 96 for (int i = 0; i < W;i++) 97 for (int j = 0; j < H; j++) 98 { 99 if (map[i][j] == '@') 100 bfs(i,j,0); 101 else if (map[i][j] == '<') 102 bfs(i,j,M+1); 103 else if (map[i][j] >= 'A' && map[i][j] <= 'J') 104 bfs(i,j,map[i][j]-'A'+1); 105 } 106 ans = -1; 107 dfs(0, 0, 0); 108 if (Case != 1) 109 puts(""); 110 printf("Case %d: ", Case++); 111 if (ans == -1){ 112 puts("Impossible"); 113 } 114 else{ 115 printf("The best score is %d. ", ans); 116 } 117 } 118 return 0; 119 }