hdu 3681 压缩dp+搜索

题意:一个机器人想越狱,他只能带一定电量的电池,'S'表示道路可行,'G'表示充电器, 只可充电一次,但是可以经过很多次。'F'表示起点,'Y'表示要破坏的机关,也是只能破坏一次,但是可以经过无数次。'D'表示不能经过的地点。求他能 破坏所有机关,带的最小初始电量。

链接:点我

真是神烦无比啊啊,这题

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 #define MOD 1000000007
 10 const int INF=0x3f3f3f3f;
 11 const double eps=1e-5;
 12 typedef long long ll;
 13 #define cl(a) memset(a,0,sizeof(a))
 14 #define ts printf("*****
");
 15 const int MAXN=17;
 16 int n,m,tt;
 17 int d[4][2]={0,1,0,-1,1,0,-1,0};
 18 int dp[1<<MAXN][MAXN];
 19 char s[MAXN][MAXN];
 20 int dist[MAXN][MAXN][MAXN][MAXN];
 21 int cnt;
 22 int start;
 23 int fin=0;
 24 bool vis[MAXN][MAXN];
 25 struct Node
 26 {
 27     int x,y;
 28 }node[MAXN],st,ed;
 29 void bfs(int x,int y)   //x,y点到其他点的距离
 30 {
 31     cl(vis);
 32     if(s[x][y]=='D')return;//这个点的不需要处理
 33     queue<Node> q;
 34     for(int i=0;i<n;i++)
 35     {
 36         for(int j=0;j<m;j++)
 37         {
 38             dist[x][y][i][j]=-1;
 39         }
 40     }
 41     while(!q.empty())   q.pop();
 42     Node now,next;
 43     now.x=x,now.y=y;
 44     dist[x][y][x][y]=0;
 45     q.push(now);
 46     vis[x][y]=1;
 47     while(!q.empty())
 48     {
 49         now=q.front();
 50         q.pop();
 51         for(int i=0;i<4;i++)
 52         {
 53             next.x=now.x+d[i][0];
 54             next.y=now.y+d[i][1];
 55             if(!vis[next.x][next.y]&&next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&s[next.x][next.y]!='D')
 56             {
 57                 if(dist[x][y][next.x][next.y]!=-1)continue;
 58                 dist[x][y][next.x][next.y]=dist[x][y][now.x][now.y]+1;
 59                 q.push(next);
 60                 vis[next.x][next.y]=1;
 61             }
 62         }
 63     }
 64 }
 65 bool check(int v)
 66 {
 67     memset(dp,-1,sizeof(dp));
 68     dp[1<<start][start]=v;
 69     for(int i=0;i<(1<<cnt);i++)
 70         for(int j=0;j<cnt;j++)
 71         {
 72             if(i==j)    continue;
 73             if((i&(1<<j))==0) continue;   //去过了
 74             if(dp[i][j]==-1)continue;
 75             if((i&fin)==fin)    return 1;
 76             for(int k=0;k<cnt;k++)
 77             {
 78                 if((i&(1<<k)))    continue;
 79                 int dis=dist[node[j].x][node[j].y][node[k].x][node[k].y];
 80                 if(dis==-1||dp[i][j]<dis)   continue;
 81                 dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]-dis);
 82                 if(s[node[k].x][node[k].y]=='G')dp[i|(1<<k)][k]=v;
 83             }
 84         }
 85     return 0;
 86 }
 87 int main()
 88 {
 89     int i,j,k;
 90     #ifndef ONLINE_JUDGE
 91     freopen("1.in","r",stdin);
 92     #endif
 93     while(scanf("%d%d",&n,&m)!=EOF)
 94     {
 95         if(n==0&&m==0)  break;
 96         for(i=0;i<n;i++)    scanf("%s",s[i]);
 97         for(i=0;i<n;i++)
 98         {
 99             for(j=0;j<m;j++)
100             {
101                 bfs(i,j);
102             }
103         }
104         cnt=0;
105         fin=0;
106         for(i=0;i<n;i++)
107         {
108             for(j=0;j<m;j++)
109             {
110                 if(s[i][j]=='F')
111                 {
112                     start=cnt;
113                     fin|=(1<<cnt);
114                     node[cnt].x=i;
115                     node[cnt++].y=j;
116                 }
117                 else if(s[i][j]=='Y')
118                 {
119                     fin|=(1<<cnt);
120                     node[cnt].x=i;
121                     node[cnt++].y=j;
122                 }
123                 else if(s[i][j]=='G')
124                 {
125                     node[cnt].x=i;
126                     node[cnt++].y=j;
127                 }
128             }
129         }
130         int l=0;
131         int r=n*m;
132         int ans=-1;
133         while(l<=r)
134         {
135             int mid=(l+r)>>1;
136             if(check(mid))
137             {
138                 ans=mid;
139                 r=mid-1;
140             }
141             else l=mid+1;
142         }
143         printf("%d
",ans);
144     }
145 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4500011.html