HDOJ--3681--Prison Break(BFS预处理+状态压缩DP)

Posted 逃往火星的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ--3681--Prison Break(BFS预处理+状态压缩DP)相关的知识,希望对你有一定的参考价值。

题意

F--起点

S--空格

G--能量池,只能充一次电,充完之后G变为S,也可已选择不充而当成普通的S

D--激光区,不能走

Y--电源开关

M被关在一所监狱之中,F为起点,每走一步(上下左右)消耗1节能量,只要关闭完所有的Y就可以直接飞出去,可以到能量池里进行充电。问M要想出去所携带的电池的最小尺寸是多少。注意:能量池和开关的总和小于15。

思路

首先将图中所有的F,G,Y找出来,并用BFS求出这三种标志任意两者的距离。具体看例子

GDDSS
SSSFS
SYGYS
SGSYS
SSYSS
//经处理后变为
F--0:  1,3
Y--1:  2,1
Y--2:  2,3
Y--3:  3,3
Y--4:  4,2
G--5:  0,0
G--6:  2,2
G--7:  3,1//之所以要先F再Y再G是为了状压的时候只要考虑前5个点(0~4)都走过(即都变成1)时方便处理。

//经BFS后记录任意亮点的距离(无视充电池,但要考虑激光区)
0,0--0
0,1--3
0,2--1
0,3--2
0,4--4
0,5--4
0,6--2
0,7--4
1,0--3
1,1--0
1,2--2
1,3--3
1,4--3
1,5--3
1,6--1
1,7--1
2,0--1
2,1--2
2,2--0
2,3--1
2,4--3
2,5--5
2,6--1
2,7--3
3,0--2
3,1--3
3,2--1
3,3--0
3,4--2
3,5--6
3,6--2
3,7--2
4,0--4
4,1--3
4,2--3
4,3--2
4,4--0
4,5--6
4,6--2
4,7--2
5,0--4
5,1--3
5,2--5
5,3--6
5,4--6
5,5--0
5,6--4
5,7--4
6,0--2
6,1--1
6,2--1
6,3--2
6,4--2
6,5--4
6,6--0
6,7--2
7,0--4
7,1--1
7,2--3
7,3--2
7,4--2
7,5--4
7,6--2
7,7--0

状态转移方程要设一个辅助的dp用来存当前走了都少步,遇到能量池时步数变为0;dp_v用来存走到当前状态历史最大的步数 。//不好理解

dp[i+sta[j]][j]=dp[i][k]+g[k][j];  或   dp[i+sta[j]][j]=0;

dp_v[i+sta[j][j]=max(dp[i+sta[j]][j],dp_v[i][k]);

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
int sta[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
int dp[32768][20];
int dp_v[32768][20];
int flag[32768][20];
int g[20][20];
char Map[20][20],c;
int N,M,ctor,nY;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
const int INF=0x7fffffff;

struct node
{
     int x,y;
};
node a[20],temp;
struct tool
{
    int num,step;
};
tool t[20][20];

//预处理
void import();
void init();
void BFS();


int main()
{
    while(scanf("%d%d",&N,&M)&&N&&M)
    {
        init();
        import();
        BFS();
        int ans=INF;
        int ans1=INF;
        int jud=sta[nY]-1;
        int jx=sta[ctor]-1;
        queue<node>q;
        while(!q.empty()) q.pop();
        temp.x=1;
        temp.y=0;
        dp[temp.x][temp.y]=0;
        dp_v[temp.x][temp.y]=0;
        flag[temp.x][temp.y]=0;
        q.push(temp);
        while(!q.empty())
        {
            int i=q.front().x;
            int k=q.front().y;
            q.pop();
            flag[i][k]=1;
            for(int j=0;j<ctor;++j)
            {

                if((sta[j]&i)==0&&g[k][j]!=-1)
                {
                    temp.x=i+sta[j];
                    temp.y=j;
                    if(j<nY&&(dp_v[temp.x][temp.y]==-1||dp_v[temp.x][temp.y]>max(dp[i][k]+g[k][j],dp_v[i][k])))
                    {
                         dp[temp.x][temp.y]=dp[i][k]+g[k][j];
                         dp_v[temp.x][temp.y]=max(dp[temp.x][temp.y],dp_v[i][k]);
                         if((temp.x&jud)==jud)
                         {
                              ans=min(ans,dp_v[temp.x][temp.y]);

                         }
                         else if(temp.x<jx&&flag[temp.x][temp.y])
                         {
                             q.push(temp);
                             flag[temp.x][temp.y]=0;
                         }
                    }
                    if(j>=nY&&(dp_v[temp.x][temp.y]==-1||dp_v[temp.x][temp.y]>max(dp[i][k]+g[k][j],dp_v[i][k])))
                    {

                         dp[temp.x][temp.y]=0;
                         dp_v[temp.x][temp.y]=max(dp[i][k]+g[k][j],dp_v[i][k]);
                        if(temp.x<jx&&flag[temp.x][temp.y])
                         {
                             q.push(temp);
                             flag[temp.x][temp.y]=0;
                         }
                    }
                }
            }
        }
        if(N==1&&M==1)
            printf("0\n");
        else if(ans==INF)
            printf("-1\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}

void init()
{
    memset(g,-1,sizeof(g));
    memset(flag,-1,sizeof(flag));
    memset(dp,-1,sizeof(dp));
    memset(dp_v,-1,sizeof(dp));
    for(int i=0;i<N;++i)
    {
        for(int j=0;j<M;++j)
        {
            t[i][j].num=-1;
            t[i][j].step=-1;
        }
    }
}
void BFS()
{
    for(int i=0;i<ctor;++i)
    {
        for(int I=0;I<N;++I) for(int J=0;J<M;++J)   t[I][J].step=-1;

        queue<node>q;
        temp.x=a[i].x;
        temp.y=a[i].y;
        t[temp.x][temp.y].step=0;
        q.push(temp);
        while(!q.empty())
        {
            int x=q.front().x;
            int y=q.front().y;
            q.pop();
            for(int j=0;j<4;++j)
            {
                temp.x=x+dx[j];
                temp.y=y+dy[j];
                if(temp.x>=0&&temp.x<N&&temp.y>=0&&temp.y<M&&Map[temp.x][temp.y]!=‘D‘&&(t[temp.x][temp.y].step==-1||t[temp.x][temp.y].step>t[x][y].step+1))
                {
                    t[temp.x][temp.y].step=t[x][y].step+1;
                    q.push(temp);
                }
            }
        }
        for(int I=0;I<N;++I)
        {
            for(int J=0;J<M;++J)
            {
                int j=t[I][J].num;
                if(j!=-1)
                {
                    g[i][j]=t[I][J].step;
                }
            }
        }
    }
}

void import()
{
    for(int i=0;i<N;++i)
        {
            for(int j=0;j<M;++j)
            {
                cin>>c;
                Map[i][j]=c;
            }
        }
        ctor=0;
        for(int i=0;i<N;++i)
        {
            for(int j=0;j<M;++j)
            {
                if(Map[i][j]==‘F‘)
                {
                    a[ctor].x=i;
                    a[ctor].y=j;
                    t[i][j].num=ctor;
                    ++ctor;
                }
            }
        }
        for(int i=0;i<N;++i)
        {
            for(int j=0;j<M;++j)
            {
                if(Map[i][j]==‘Y‘)
                {
                    a[ctor].x=i;
                    a[ctor].y=j;
                    t[i][j].num=ctor;
                    ++ctor;
                }
            }
        }
        nY=ctor;
        for(int i=0;i<N;++i)
        {
            for(int j=0;j<M;++j)
            {
                if(Map[i][j]==‘G‘)
                {
                    a[ctor].x=i;
                    a[ctor].y=j;
                    t[i][j].num=ctor;
                    ++ctor;
                }
            }
        }
}

  

 

 

---恢复内容结束---

以上是关于HDOJ--3681--Prison Break(BFS预处理+状态压缩DP)的主要内容,如果未能解决你的问题,请参考以下文章

break是终止本次循环还是结束循环

CSS中的“word-break:break-all”与“word-wrap:break-word”有啥区别

break语句与continue语句

break和continue的区别

switch 中没有break 如何执行

break ,continue ,return 的区别及作用?