hdu 1044 Collect More Jewels

并没有做过这种类型的题目,不太会做...看了一下大神的代码,然后自己敲...额..思路一样了,代码也差不多..

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 }
View Code
原文地址:https://www.cnblogs.com/xiaoniuniu/p/4511362.html