赞
踩
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1044
此题系BFS和DFS的结合使用,需要理解BFS和DFS的特点。
BFS:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费较大,需要开辟大量的数组单元来存储状态。
DFS:对于解决遍历和求所有问题有效,对于问题搜索深度小的时候处理迅速,然而在深度很大的情况下效率不高。
问题:在能够走出迷宫的前提下,如何尽可能多(价值之和大)的收集珠宝?
分析:
1、从题目可知,珠宝的数目及每个珠宝的价值我们能够知道,要求“最多”,我们通常会联想到动态规划。但从题目本身看,我们很难看到动态规划的影子。于是我们可以考虑构造动态规划的条件。
2、于是就有了这样的Idea:用BFS,先将“起始点--珠宝”、“珠宝--珠宝”、“珠宝—出口”两两间的最短距离求出来,构造一个新的图,用marix存储,matrix的每个元素即两个点之间的最短距离。
3、然后我们就可以利用动态规划(即这里的DFS)来求满足条件(能够走出迷宫;收集价值量最大的珠宝)的最优路径。
- #include<iostream>
- #include<queue>
- #include<ctype.h>
- #include<string.h>
- using namespace std;
-
- int T, W, H, M, L;
- char dungeon[60][60];
- int newMap[60][60];
- int value[60];
- int totalValue;
- int dis[60][60];
- int visited1[60][60];
- int visited2[60];
- int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
- int res;
-
- typedef struct{
- int x;
- int y;
- }Pos;
-
- queue<Pos> que;
-
- void bfs(int y, int x, int p)
- {
- int i;
-
- while(!que.empty()){
- que.pop();
- }
- Pos cur;
- cur.x = x;
- cur.y = y;
- visited1[y][x] = 1;
- dis[y][x] = 0;
- que.push(cur);
- while(!que.empty()){
- cur = que.front();
- que.pop();
- for(i=0; i<4; i++){
- Pos next;
- next.y = cur.y + dir[i][0];
- next.x = cur.x + dir[i][1];
- if(next.y>=H || next.y<0 || next.x>=W || next.x<0){
- continue;
- }
- if(visited1[next.y][next.x]==0 && dungeon[next.y][next.x]!='*'){
- visited1[next.y][next.x] = 1;
- dis[next.y][next.x] = dis[cur.y][cur.x] + 1;
- if(dungeon[next.y][next.x] == '@'){
- newMap[p][0] = dis[next.y][next.x];
- }
- if(isalpha(dungeon[next.y][next.x])){
- newMap[p][dungeon[next.y][next.x]-64] = dis[next.y][next.x];
- }
- if(dungeon[next.y][next.x] == '<'){
- newMap[p][M+1] = dis[next.y][next.x];
- }
- que.push(next);
- }
- }
- }
- }
-
- void dfs(int p, int v, int time)
- {
- if(time>L || res==totalValue){
- return ;
- }
- if(p>M && v>res){ //p=M+1说明能够走出去,当v>res时更新res
- res = v;
- }
- for(int i=0; i<=M+1; i++){
- if(newMap[p][i]==0 || visited2[i]){
- continue;
- }
- visited2[i] = 1;
- dfs(i, v+value[i], time+newMap[p][i]);
- visited2[i] = 0;
- }
- }
-
-
- int main()
- {
- int i, j, k, x;
-
- scanf("%d", &T);
- x = 1;
- while(T--){
- memset(visited2, 0, sizeof(visited2));
- memset(value, 0, sizeof(value));
- memset(newMap, 0, sizeof(newMap));
- scanf("%d%d%d%d", &W, &H, &L, &M);
- totalValue = 0; //totalValue是一个剪枝条件,不考虑会超时
- for(j=1; j<=M; j++){
- scanf("%d", &value[j]);
- totalValue += value[j];
- }
- value[0] = value[M+1] = 0;
- for(j=0; j<H; j++){
- scanf("%s", dungeon[j]);
- }
-
- for(i=0; i<H; i++){
- for(j=0; j<W; j++){
- memset(visited1, 0, sizeof(visited1));
- memset(dis, 0, sizeof(dis));
- if(dungeon[i][j]=='@'){
- bfs(i, j, 0);
- }
- if(isalpha(dungeon[i][j])){
- bfs(i, j, dungeon[i][j]-64);
- }
- if(dungeon[i][j] == '<'){
- bfs(i, j, M+1);
- }
- }
- }
- res = -1;
- visited2[0] = 1;
- dfs(0, 0, 0);
-
- printf("Case %d:\n", x++);
- if(res >= 0){
- printf("The best score is %d.\n", res);
- }
- else{
- printf("Impossible\n");
- }
- if(T){
- printf("\n");
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。