zoukankan      html  css  js  c++  java
  • 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
    ");
            else if(ans==INF)
                printf("-1
    ");
            else
                printf("%d
    ",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;
                    }
                }
            }
    }
    

      

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

  • 相关阅读:
    SVN与TortoiseSVN实战:标签与分支
    IOS性能调优系列:使用Zombies动态分析内存中的僵尸对象
    IOS性能调优系列:使用Allocation动态分析内存使用情况
    IOS性能调优系列:使用Instruments动态分析内存泄漏
    IOS性能调优系列:Analyze静态分析
    2014年个人知乎收藏夹整理
    IOS开发环境更换后重新制作Provisioning Profile证书详解
    使用VS2010编译MongoDB C++驱动详解
    ACE服务端编程1:使用VS2010编译ACE6.0及从ACE5.6升级的注意事项
    std::string在多字节字符集环境下substr的实现方法
  • 原文地址:https://www.cnblogs.com/l1l1/p/8641494.html
Copyright © 2011-2022 走看看