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\n",ans);
147     }
148     return 0;
149 }
View Code

 

posted @ 2014-10-17 15:15  null1019  阅读(173)  评论(0编辑  收藏  举报