zoukankan      html  css  js  c++  java
  • hdu 3681 Prison Break

    http://acm.hdu.edu.cn/showproblem.php?pid=3681

    题意:一个n*m的矩阵,'F'是起点。机器人从F出发,走到G可以充电,走到Y关掉开关,D不能走进,要求把所有开关关掉,且电量最少,并求出该最小电量。

    把F,G,Y的坐标存起来,然后用bfs求出它们每两个点最短距离,然后用dp判断是不是可以满足目的状态。 用二分枚举答案。

      1 #include <cstdio>
      2 #include <queue>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define maxn 17
      6 using namespace std;
      7 const int inf=1<<29;
      8 
      9 char g[16][16];
     10 int n,m;
     11 int gg[16][16];
     12 bool vis[16][16];
     13 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
     14 int sx,sy;
     15 int spos;
     16 int epos;
     17 int cnt;
     18 int dis[16][16];
     19 int dp[(1<<maxn)][maxn];
     20 struct node
     21 {
     22     int x,y;
     23 }p[16],st,st1,st2;
     24 
     25 int bfs(int s,int t)
     26 {
     27     queue<node>q;
     28     memset(vis,false,sizeof(vis));
     29     for(int i=0; i<n; i++)
     30     {
     31         for(int j=0; j<m; j++)
     32         {
     33             dis[i][j]=inf;
     34         }
     35     }
     36     dis[p[s].x][p[s].y]=0;
     37     st.x=p[s].x;
     38     st.y=p[s].y;
     39     vis[p[s].x][p[s].y]=true;
     40     q.push(st);
     41     while(!q.empty())
     42     {
     43         st1=q.front();
     44         q.pop();
     45         if(st1.x==p[t].x&&st1.y==p[t].y)
     46         {
     47             return dis[st1.x][st1.y];
     48         }
     49         for(int i=0; i<4; i++)
     50         {
     51             int xx=st1.x+dir[i][0];
     52             int yy=st1.y+dir[i][1];
     53             if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&g[xx][yy]!='D')
     54             {
     55                 dis[xx][yy]=dis[st1.x][st1.y]+1;
     56                 st2.x=xx;
     57                 st2.y=yy;
     58                 vis[xx][yy]=true;
     59                 q.push(st2);
     60             }
     61         }
     62     }
     63     return -1;
     64 }
     65 
     66 int ok(int c)
     67 {
     68     memset(dp,-1,sizeof(dp));
     69     dp[1<<spos][spos]=c;
     70     for(int i=0; i<(1<<cnt); i++)
     71     {
     72         for(int j=0; j<cnt; j++)
     73         {
     74             if((i&(1<<j))==0) continue;
     75             if(dp[i][j]==-1) continue;
     76             if((i&epos)==epos) return true;
     77             for(int k=0; k<cnt; k++)
     78             {
     79                 if(i&(1<<k)) continue;
     80                 if(gg[j][k]==-1) continue;
     81                 if(dp[i][j]<gg[j][k]) continue;
     82                 if(dp[i|(1<<k)][k]==-1) dp[i|(1<<k)][k]=dp[i][j]-gg[j][k];
     83                 else dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]-gg[j][k]);
     84                 int x1=p[k].x,y1=p[k].y;
     85                 if(g[x1][y1]=='G') dp[i|(1<<k)][k]=c;
     86             }
     87         }
     88     }
     89     return false;
     90 }
     91 
     92 int main()
     93 {
     94     while(scanf("%d%d",&n,&m)!=EOF)
     95     {
     96         if(n==0&&m==0) break;
     97         cnt=0;
     98         epos=0;
     99         for(int i=0; i<n; i++)
    100         {
    101             scanf("%s",g[i]);
    102             for(int j=0; j<m; j++)
    103             {
    104                 if(g[i][j]=='F')
    105                 {
    106                     sx=i; sy=j;
    107                     spos=cnt;
    108                     epos|=(1<<cnt);
    109                     p[cnt].x=i;
    110                     p[cnt++].y=j;
    111                 }
    112                 if(g[i][j]=='G')
    113                 {
    114                     p[cnt].x=i;
    115                     p[cnt++].y=j;
    116                 }
    117                 if(g[i][j]=='Y')
    118                 {
    119                     epos|=(1<<cnt);
    120                     p[cnt].x=i;
    121                     p[cnt++].y=j;
    122                 }
    123             }
    124         }
    125         for(int i=0; i<cnt; i++)
    126         {
    127             for(int j=0; j<cnt; j++)
    128             {
    129                 if(i==j) gg[i][j]=0;
    130                 else gg[i][j]=bfs(i,j);
    131             }
    132         }
    133         int l=0,r=n*m;
    134         int mid;
    135         int ans=-1;
    136         while(l<=r)
    137         {
    138             mid=(l+r)>>1;
    139             if(ok(mid))
    140             {
    141                 ans=mid;
    142                 r=mid-1;
    143             }
    144             else l=mid+1;
    145         }
    146         printf("%d
    ",ans);
    147     }
    148     return 0;
    149 }
    View Code
  • 相关阅读:
    vue 路由跳转传参
    vue better-scroll 下拉上拉,加载刷新
    H5点击拨打电话,发短信
    vue搭建项目
    How to determine the socket connection up time on Linux
    @ContextConfiguration注解
    MySQL修改主键属性
    软件测试工程师面试(一)
    Python实现不同格式打印九九乘法表
    MySQL 5.1安装和配置过程中遇到的问题
  • 原文地址:https://www.cnblogs.com/fanminghui/p/4031239.html
Copyright © 2011-2022 走看看