hdu 1044 Collect More Jewels

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1044

题目大意:

在一个迷宫中,从起点走到终点,还有几个宝物,问在给定的时间内,到达终点后所能获取的最大价值。

思路:

先用bfs求出入口,宝物,出口,两两之间的最短距离。

在用dfs搜索所有情况,求出从入口走到出口能获得的最大价值。

熟悉两种搜索的优缺点:

BFS: 对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元用来存储状态)。

DFS:对于解决遍历和求所有问题有效,对于问题搜索深度小的时候处理速度迅速,然而在深度很大的情况下效率不高

 code:

View Code
  1 # include<stdio.h>

  2 # include<string.h>

  3 # include<stdlib.h>

  4 # include<queue>

  5 using namespace std;

  6 int dir[4][2]={1,0,-1,0,0,1,0,-1};

  7 int n,m,x0,y0,endx,endy,time,M,sum;

  8 int val[12];

  9 int adj[13][13],vis[55][55],Max,visit[15];

 10 char map[55][55];

 11 struct node{

 12     int x,y,step;

 13 };

 14 struct node1{

 15     int x,y;

 16 }s[13];

 17 queue<node>q;

 18 void bfs(int x1,int y1,int k)

 19 {

 20     int i,ans;

 21     while(!q.empty()) q.pop();

 22     node cur,next;

 23     cur.x=x1;

 24     cur.y=y1;

 25     cur.step=0;

 26     q.push(cur);

 27     memset(vis,0,sizeof(vis));

 28     vis[x1][y1]=1;

 29     while(!q.empty())

 30     {

 31         cur=q.front();

 32         q.pop();

 33         for(i=0;i<4;i++)

 34         {

 35             next.x=cur.x+dir[i][0];

 36             next.y=cur.y+dir[i][1];

 37             next.step=cur.step+1;

 38             if(next.x<0 || next.x>=n || next.y<0 || next.y>=m || map[next.x][next.y]=='*' || vis[next.x][next.y]) continue;

 39             vis[next.x][next.y]=1;

 40             q.push(next);

 41             if(map[next.x][next.y]>='A' && map[next.x][next.y]<='J')

 42             {

 43                 ans=map[next.x][next.y]-'A';

 44                 adj[k][ans]=adj[ans][k]=next.step;

 45             }

 46             else if(map[next.x][next.y]=='@') 

 47             {

 48                 adj[k][M]=adj[M][k]=next.step;

 49             }

 50             else if(map[next.x][next.y]=='<')

 51             {

 52                 adj[k][M+1]=adj[M+1][k]=next.step;

 53             }

 54         }

 55     }

 56 }

 57 void dfs(int i,int step,int value)

 58 {

 59     int j;

 60     if(step>time || Max==sum) return;///Max==sum这一点很重要,不加这个剪枝就直接超时了,意思是在所有能够访问到的珠宝都捡到了的时候就返回,不在搜索了。 

 61     if(i==M+1) 

 62     {

 63         if(value>Max) Max=value;

 64     }

 65     if(i!=M+1 && step+adj[i][M+1]>time) return;

 66     for(j=0;j<=M+1;j++)

 67     {

 68         if(adj[i][j]!=-1)

 69         {

 70             if(visit[j]) continue;

 71             visit[j]=1;

 72             if(j<M) dfs(j,step+adj[i][j],value+val[j]);

 73             else dfs(j,step+adj[i][j],value);

 74             visit[j]=0;

 75         }

 76     }

 77 }

 78 int main()

 79 {

 80     int i,j,t,ncase;

 81     scanf("%d",&ncase);

 82     for(t=1;t<=ncase;t++)

 83     {

 84         if(t!=1) printf("\n");

 85         scanf("%d%d%d%d",&m,&n,&time,&M);

 86         sum=0;

 87         for(i=0;i<M;i++)

 88             scanf("%d",&val[i]);

 89         for(i=0;i<n;i++)

 90         {

 91             scanf("%s",map[i]);

 92             for(j=0;j<m;j++)

 93             {

 94                 if(map[i][j]=='@') {x0=i;y0=j;}

 95                 else if(map[i][j]=='<') {endx=i;endy=j;}

 96                 else if(map[i][j]>='A' && map[i][j]<='J')

 97                 {

 98                     s[map[i][j]-'A'].x=i;

 99                     s[map[i][j]-'A'].y=j;

100                 }

101             }

102         }

103         memset(adj,-1,sizeof(adj));

104         printf("Case %d:\n",t);

105         bfs(x0,y0,M);//入口用第M个点来表示 

106         if(adj[M][M+1]==-1 || adj[M][M+1]>time) {printf("Impossible\n");continue;}

107         for(i=0;i<M;i++)

108             if(adj[i][M]!=-1) sum+=val[i];

109         bfs(endx,endy,M+1);//出口用第M+1个点来表示 

110         for(i=0;i<M;i++)

111             bfs(s[i].x,s[i].y,i);

112         Max=0;

113         memset(visit,0,sizeof(visit));

114         visit[M]=1;

115         

116         dfs(M,0,0); 

117         printf("The best score is %d.\n",Max);

118     }

119     return 0;

120 }

 

你可能感兴趣的:(more)