zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    powershell,系统学习的第一种脚本语言
    mysql的source命令
    timer--计时器
    document.write 方法
    数组去重
    Abdicate
    轮播图
    使用 margin 让div块内容居中
    模运算 NOJ 1037
    模运算 NOJ 1037
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4500011.html
Copyright © 2011-2022 走看看