1044 [Collect More Jewels] DFS+BFS

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

题目大意:在地图中,有M个宝石,每个宝石有不同价值。问在时间限制L之内,从入口到出口这一路上获得的最大价值是多少。拿宝石不额外花时间,走一格用时为1.

关键思想:考虑到BFS和DFS的特点,BFS在解决最短(小)问题是很有效,但内存耗费巨大;DFS可以解决绝大多数搜索问题,但层数较深时,时间开销和栈的开销都很大。

这道题,只用DFS显然是不行的,地图比较大了。但是只用BFS也不行,因为取完之后地图状态会发生改变,考虑这样一种情况,如果终点邻近处有一个宝石,那当你时间多的时候,是会跨过终点取完宝石再回来的。只用一种搜索不行,那两种搜索并用吧。

我们先用BFS把起点、终点、各个宝石这些重要元素之间的最短用时解出来。(只有10多个)

然后用DFS搜索从起点经过重要元素到达终点的最大收益。好好想一想为什么可以这样算,你一定能理解。

代码如下:

#include <iostream>
#include <memory.h>
#include <stdio.h>
#include <queue>
using namespace std;
const int INF=1e8;
const int MAXN=55;
const int MAXM=16;
char m[MAXN][MAXN];
int dir[4][2]={0,1,1,0,0,-1,-1,0};

int W,H,L,M,sum,ans;//L时限

struct node{
    int x,y;
    int t;
};//[0]为起点,[T+1]为终点
int v[MAXM];//0不用 

int newM[MAXM][MAXM];//构造出来的邻接矩阵 ,将重要元素作为点 

bool vis[MAXM];//DFS的时候用到
bool vis2[MAXN][MAXN];//BFS的时候用到 ,这样不会爆空间 

void dfs(int p0,int money,int time){
    if(ans==sum||time>L)return;//sum这个优化很关键,TLE和AC的差别
    if(p0==M+1){//如果到了终点,更新当前获得的钱
        ans=max(ans,money);
    }
    for(int i=1;i<=M+1;i++){
        if(!vis[i]){
            vis[i]=true;
            dfs(i,money+v[i],time+newM[p0][i]);
            vis[i]=false;
        }
    }
    return;
}

void bfs(int x,int y,int from){//bfs计算重要元素间的最短时间
    memset(vis2,0,sizeof(vis2));
    queue<node>q;
    node nw,nt;
    vis2[x][y]=true;
    nw.x=x,nw.y=y,nw.t=0;
    q.push(nw);
    while(!q.empty()){
        nw=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            nt.x=nw.x+dir[i][0];
            nt.y=nw.y+dir[i][1];
            nt.t=nw.t+1;
            if(!vis2[nt.x][nt.y]&&nt.x>=1&&nt.x<=H&&nt.y>=1&&nt.y<=W&&m[nt.x][nt.y]!=‘*‘&&nt.t<=L){//可以走的路径
                if(m[nt.x][nt.y]<=‘Z‘&&m[nt.x][nt.y]>=‘A‘&&newM[from][m[nt.x][nt.y]-‘A‘+1]==INF){//如果找到重要的点就更新最短时间,加了一点优化
                    newM[from][m[nt.x][nt.y]-‘A‘+1]=nt.t;
                    newM[m[nt.x][nt.y]-‘A‘+1][from]=nt.t;
                }
                else if(m[nt.x][nt.y]==‘@‘&&newM[from][0]==INF){
                    newM[from][0]=nt.t;
                    newM[0][from]=nt.t;
                }
                else if(m[nt.x][nt.y]==‘<‘&&newM[from][M+1]==INF){
                    newM[from][M+1]=nt.t;
                    newM[M+1][from]=nt.t;
                }
                vis2[nt.x][nt.y]=1;
                q.push(nt);
            }
        }
    }
    return;
} 

int main(){
    int T;
    scanf("%d",&T);
    for(int cnt=1;cnt<=T;cnt++){
        memset(vis,0,sizeof(vis));
        memset(newM,-1,sizeof(newM));

        scanf("%d%d%d%d",&W,&H,&L,&M);

        ans=-1;
        sum=0;//sum保存宝石总价值
        for(int i=1;i<=M;i++){scanf("%d",&v[i]);sum+=v[i];}
        v[M+1]=0; //要注意,DFS会涉及 ,终点没有宝石
        for(int i=1;i<=H;i++){
            for(int j=1;j<=W;j++){
                scanf(" %c",&m[i][j]);
            }
        }
        //新图的邻接矩阵初始化
        for(int i=0;i<=M+1;i++){
            for(int j=0;j<=M+1;j++){
                if(i!=j)newM[i][j]=INF;
                else newM[i][j]=0;
            }
        }

        //开始BFS获得重要元素间的最少耗时,要用到坐标i、j
        for(int i=1;i<=H;i++){
            for(int j=1;j<=W;j++){
                if(m[i][j]<=‘Z‘&&m[i][j]>=‘A‘){
                    bfs(i,j,m[i][j]-‘A‘+1);
                }
                else if(m[i][j]==‘@‘){
                    bfs(i,j,0);
                }
                else if(m[i][j]==‘<‘){
                    bfs(i,j,M+1);
                }
            }
        }

        printf("Case %d:\n",cnt);
        //newM[0][M+1]<=L
        if(newM[0][M+1]<=L){//如果起点到终点最短距离都大于L那肯定不行
            dfs(0,0,0);
            printf("The best score is %d.\n",ans);
        }
        else printf("Impossible\n");
        if(cnt!=T)printf("\n");
    }
    return 0;
}
时间: 2024-10-25 05:51:45

1044 [Collect More Jewels] DFS+BFS的相关文章

HDU 1044 Collect More Jewels【BFS+DFS+建立距离图】

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6707    Accepted Submission(s): 1556 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

HDU 1044 Collect More Jewels 【经典BFS+DFS】

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6597    Accepted Submission(s): 1527 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

Collect More Jewels(hdu1044)(BFS+DFS)

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6857    Accepted Submission(s): 1592 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

hdu.1044.Collect More Jewels(bfs + 状态压缩)

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5345    Accepted Submission(s): 1189 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

HDU ACM 1044 Collect More Jewels BFS+DFS

题意:在一个迷宫中,有一些宝物,从起点走到终点,问在给定的时间内,到达终点后所能拾取珠宝的最大价值. 分析(BFS+DFS): 1.求入口到第一个取宝物的地方的最短距离 2.求第i个取宝物的地方到第i+1个取宝物的地方的最短距离 3.求第n个取宝物的地方到出口的最短距离 4.保证以上3点能在时间L内实现的情况下,取得的宝石价值最大. BFS特点:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元来存储状态) DFS特点:对于解决遍历和求所有问题有效,对于问

hdu 1044 Collect More Jewels

并没有做过这种类型的题目,不太会做...看了一下大神的代码,然后自己敲...额..思路一样了,代码也差不多.. http://www.cnblogs.com/kuangbin/archive/2012/08/14/2637512.html 先通过BFS预处理任意两点之间的距离,然后通过DFS暴力模拟路径,算出最优解. 感觉自己可能对BFS理解比DFS更深一点,或者说,BFS比较简单一点吧... 这题还有一种解法是状态压缩+BFS...通过开设一个int型变量记录是否拿到宝物,然后暴力..不过这种

HDU Collect More Jewels 1044

BFS + 状态压缩 险过 这个并不是最好的算法 但是写起来比较简单 , 可以AC,但是耗时比较多 下面是代码 就不多说了 #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; #define Max(a,b) (a>b?a:b) #define Min(a,b) (a

HDU 4771 (DFS+BFS)

Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his precious with him. As you know,

HDU 4771 Stealing Harry Potter&#39;s Precious dfs+bfs

Stealing Harry Potter's Precious Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his