码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5025 (BFS+记忆化状压搜索)

时间:2014-10-15 20:15:01      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:style   http   color   io   os   使用   ar   for   strong   

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

题目大意: 迷宫中孙悟空救唐僧,可以走回头路。必须收集完钥匙,且必须按顺序收集。迷宫中还有蛇,杀蛇多耗时1,蛇杀完就没了。问最少耗时。

解题思路

2014广州网赛的水题之一。当时没刷过BFS状压,结果悲剧了。

首先这题可以压钥匙,也可以压蛇,不过压钥匙内存岌岌可危,于是就压蛇吧。

设f[x][y][key][snake]为在(x,y)点,已经取得的钥匙key,以及杀蛇snake的状态。

对于钥匙k,如果k==key+1,那么 key++

对于蛇k,如果!snake&(1<<k)那么dep++

其他情况则dep++即可

由于杀蛇导致BFS树同层分布不均衡,可以使用优先队列来优化。不过维护优先队列需要时间,可能效果适得其反orz。

 

#include "cstdio"
#include "string"
#include "cstring"
#include "iostream"
#include "queue"
using namespace std;
struct status
{
    int x,y,dep,key,snake;
    status(int x,int y,int dep,int key,int snake):x(x),y(y),dep(dep),key(key),snake(snake) {}
    bool operator < (const status &a) const {return dep > a.dep;}
};
char map[105][105];
int n,m,sx,sy,ex,ey,f[105][105][10][35],dir[4][2]={-1,0,1,0,0,-1,0,1},ans;
void bfs(int x,int y)
{
    priority_queue<status> Q;
    Q.push(status(x,y,0,0,0)) ;
    f[x][y][0][0]=1;
    bool flag=false;
    while(!Q.empty())
    {
        if(flag) break;
        status t=Q.top();Q.pop();
        for(int s=0;s<4;s++)
        {
            int X=t.x+dir[s][0],Y=t.y+dir[s][1],key=t.key,snake=t.snake,dep=t.dep;
            if(X<1||X>n||Y<1||Y>n||map[X][Y]==#) continue;
            if(isdigit(map[X][Y]))
            {
                int k=map[X][Y]-0;
                if(k==t.key+1) key++;
            }
            if(islower(map[X][Y]))
            {
                int k=map[X][Y]-a;
                if(!(snake&(1<<k))) {snake=snake|(1<<k);dep++;}
            }
            dep++;
            if(f[X][Y][key][snake]) continue;
            f[X][Y][key][snake]=1;
            if(X==ex&&Y==ey&&key==m) {flag=true;ans=min(ans,dep);}
            Q.push(status(X,Y,dep,key,snake));
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    string tt;
    while(cin>>n>>m&&n)
    {
        int snake_cnt=a;
        memset(f,0,sizeof(f));
        ans=1<<28;
        for(int i=1;i<=n;i++)
        {
            cin>>tt;
            for(int j=0;j<tt.size();j++)
            {
                map[i][j+1]=tt[j];
                if(tt[j]==K) {sx=i;sy=j+1;}
                if(tt[j]==T) {ex=i;ey=j+1;}
                if(tt[j]==S) map[i][j+1]=snake_cnt++;
            }
        }
        bfs(sx,sy);
        if(ans==1<<28) cout<<"impossible"<<endl;
        else cout<<ans<<endl;
    }
}

 

11878237 2014-10-15 16:46:24 Accepted 5025 812MS 15480K 2076 B C++ Physcal

HDU 5025 (BFS+记忆化状压搜索)

标签:style   http   color   io   os   使用   ar   for   strong   

原文地址:http://www.cnblogs.com/neopenx/p/4026803.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!