题目链接:哆啦A梦传送门
参考链接:https://www.cnblogs.com/kuangbin/archive/2012/08/14/2637512.html
题意:给一个迷宫图,让你在不超过时间L的情况下从起点走到终点,图中有些点是有宝藏的,经过这个点会得到相应的宝藏价值,'@'表示起点,'<'表示终点,'*'表示墙,'.'表示空地,‘A'~’J'表示宝藏;
题解:我们先设起点为0,终点为M+1,宝藏点为相应的字符顺序。
那么我们先bfs找出任意两点的最短距离,也就是走到此点的时间。
最后我们dfs找出源点到终点的最大值。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int dis[55][55];///存储两点之间的最短距离
int step[55][55];///bfs时记录步数
int used[55][55];///bfs时标记此点是否访问
char maps[55][55];
int val[15];///存储宝藏的值
int sum;///存储珠宝总价值
int vis[55];///dfs标记此点是否访问
int ans;///结果最大值
int W,H,L,M;
int dx[4][2]={0,1,0,-1,1,0,-1,0};
queue<int> que;
///bfs,找s到其它点(1~M)的最短距离
void bfs(int x1,int y1,int s)
{
while(!que.empty()) que.pop();
memset(used,0,sizeof(used));
memset(step,0,sizeof(step));
used[x1][y1]=1;
step[x1][y1]=0;
que.push(x1*W+y1);///把此点push进去
while(!que.empty())
{
int t=que.front();
que.pop();
int x=t/W;
int y=t%W;
for(int i=0;i<4;i++)
{
int xx=x+dx[i][0];
int yy=y+dx[i][1];
if(xx<0||xx>=H||yy<0||yy>=W) continue;
if(used[xx][yy]||maps[xx][yy]=='*') continue;
used[xx][yy]=1;
step[xx][yy]=step[x][y]+1;
if(maps[xx][yy]=='@'){
dis[s][0]=step[xx][yy];
}
else if(maps[xx][yy]=='<')
dis[s][M+1]=step[xx][yy];
else if(maps[xx][yy]>='A'&&maps[xx][yy]<='J')
dis[s][maps[xx][yy]-'A'+1]=step[xx][yy];
que.push(xx*W+yy);
}
}
return;
}
void dfs(int s,int value,int time)
{
///剪枝
if(time>L) return; ///时间超过L
if(ans==sum) return;
if(s>M){ ///到达终点
ans=max(ans,value);
return;
}
for(int i=0;i<=M+1;i++)
{
if(vis[i]||dis[s][i]==0) continue;
vis[i]=1;
dfs(i,value+val[i],time+dis[s][i]);
vis[i]=0;
}
return;
}
int main()
{
int ncase;
scanf("%d",&ncase);
int T=0;
while(ncase--)
{
scanf("%d%d%d%d",&W,&H,&L,&M);
sum=0;
for(int i=1;i<=M;i++)
scanf("%d",&val[i]),sum+=val[i];
memset(dis,0,sizeof(dis));
val[0]=0;val[M+1]=0;///起点和终点都为价值都为0
for(int i=0;i<H;i++)
scanf("%s",&maps[i]);
for(int i=0;i<H;i++)
for(int j=0;j<W;j++)
{
if(maps[i][j]=='@'){///定义起点为第0个点
bfs(i,j,0);
}
else if(maps[i][j]=='<') ///终点为第M+1个点
bfs(i,j,M+1);
else if(maps[i][j]>='A'&&maps[i][j]<='J')
bfs(i,j,maps[i][j]-'A'+1);
}
memset(vis,0,sizeof(vis)); ///初始化
vis[0]=1;
ans=-1;
dfs(0,0,0);
printf("Case %d:\n",++T);
if(ans>=0) printf("The best score is %d.\n",ans);
else printf("Impossible\n");
if(ncase) puts("");
}
return 0;
}
我虽说不爱这类dfs,bfs,但我还是要做。