Description:
在这个问题中,冒险家您处于危险的地牢中。您被告知地牢即将崩溃。您必须在给定的时间内找到出口楼梯。但是,您不想空手而归。地牢中有很多稀有珠宝。离开之前,请尝试收集其中的一些物品。有些珠宝更便宜,有些更贵,由A~J来表示,‘*’为墙壁,不能通过,‘.’为空地可以走,‘@’为初始位置,‘<’为出口。因此,您将尽最大的努力来最大化您的收藏,更重要的是,及时离开地牢。
Sample Input 3 4 4 2 2 100 200 **** *@A* *B<* **** 4 4 1 2 100 200 **** *@A* *B<* **** 12 5 13 2 100 200 ************ *B.........* *.********.* *@...A....<* ************ Sample Output Case 1: The best score is 200. Case 2: Impossible Case 3: The best score is 300.
代码如下:用BFS来对每张地图的路线进行规划(分别从@,A~J ,‘<’到 终点‘<’的路线规划),用DFS来选取珠宝,使珠宝最大值尽可能大,同时在规定时间到达门口。
#include<iostream> #include<queue> #include<string.h> using namespace std; char a[55][55];// int dis[55][55];// 多张地图记录多张地图的步数 int step[55][55]; //一张地图的步数 bool vis[55][55];//判断是否访问过 bool mark[55]; //标记每个物品取走了没有 int val[55];//物品价值 int w,h,t,n; int sum,ans; int dir[4][2]={1,0,0,1,-1,0,0,-1}; bool OK(int x,int y) { if(x<0||x>=h||y<0||y>=w) return false; return true; } void BFS(int x,int y,int idx) { queue<int>q; while(!q.empty()) q.pop(); memset(step,0,sizeof(step)); memset(vis,false,sizeof(vis)); step[x][y]=0; vis[x][y]=true; int p=x*w+y; q.push(p); while(!q.empty()) { p= q.front(); q.pop(); int x = p/w; int y = p%w; for(int i=0 ;i<4; i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(OK(xx,yy)&&!vis[xx][yy]&&a[xx][yy]!='*') { vis[xx][yy]=true; step[xx][yy] =step[x][y]+1; if(a[xx][yy]=='@') dis[idx][0]=step[xx][yy]; else if(a[xx][yy]=='<') dis[idx][n+1]=step[xx][yy]; else if(a[xx][yy]>='A'&&a[xx][yy]<='J') dis[idx][a[xx][yy]-'A'+1]=step[xx][yy]; q.push(xx*w+yy); } } } } void DFS(int s,int value,int time) { if(time > t) return; if(ans==sum) return ; if(s>n) { if(value >ans) ans = value; return ; } for(int i=0 ;i<=n+1;i++) { if(mark[i]||dis[s][i]==0) continue; mark[i]=true; DFS(i,value+val[i],time+dis[s][i]); // 第i个物品 ,价值, 时间 mark[i]=false; } } int main() { int T,kcase=0; cin >> T; while(T--) { cin >> w>> h>> t>> n; sum=0; for(int i=1 ;i<=n ;i++) { cin >> val[i]; sum+=val[i]; } val[0]=val[n+1]=0; for(int i=0 ;i<h ;i++) cin >> a[i]; memset(dis,0,sizeof(dis)); for(int i=0 ;i<h ;i++) { for(int j=0 ;j<w; j++) { if(a[i][j]=='@') BFS(i,j,0); //不寻找珠宝的情况 else if(a[i][j]=='<') BFS(i,j,n+1); //将出口视为第n+1个珠宝 else if(a[i][j]>='A'&&a[i][j]<='J') BFS(i,j,a[i][j]-'A'+1); //分别从A~J出发到大门的情况 } } memset(mark,false,sizeof(mark)); mark[0]=true; ans=-1; DFS(0,0,0); cout << "Case "<< ++kcase<< ":"<<endl; if(ans>=0) cout <<"The best score is "<<ans <<"."<<endl; else cout << "Impossible"<<endl; if(T) cout <<endl; } return 0; }