HDOJ-1044 Collect More Jewels(BFS + DFS)

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;
}

 

posted @ 2020-08-29 21:36  Jesen等不等式  阅读(126)  评论(0编辑  收藏  举报