hdu 3681(bfs+二分+状压dp判断)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681

思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题。首先bfs预处理出‘Y',’F','G'之间的最短距离,由于G点可以充电,到达G点就把当前能量更新为电池容量然后继续走。因为每个G点只能充一次电,这就好像TSP中的每个点只能走一次一样,然后就是二分答案了,用状压DP判定当前电池容量的情况下是否能符合条件。

  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<queue>

  6 using namespace std;

  7 

  8 struct Node{

  9     int x,y;

 10 }node[17*17];

 11 

 12 int dist[17][17][17][17];

 13 int dp[1<<17][17];

 14 int n,m,state,final_state,start;

 15 char map[17][17];

 16 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

 17 

 18 void bfs(Node &node)

 19 {

 20     queue<pair<int,int> >que;

 21     que.push(make_pair(node.x,node.y));

 22     dist[node.x][node.y][node.x][node.y]=0;

 23     while(!que.empty()){

 24         int x=que.front().first,y=que.front().second;

 25         que.pop();

 26         for(int i=0;i<4;i++){

 27             int xx=x+dir[i][0],yy=y+dir[i][1];

 28             if(xx>=0&&xx<n&&yy>=0&&yy<m&&map[xx][yy]!='D'){

 29                 if(dist[node.x][node.y][xx][yy]==-1){

 30                     dist[node.x][node.y][xx][yy]=dist[node.x][node.y][x][y]+1;

 31                     que.push(make_pair(xx,yy));

 32                 }

 33             }

 34         }

 35     }

 36 }

 37 

 38 

 39 bool Judge(int Power)

 40 {

 41     memset(dp,-1,sizeof(dp));

 42     dp[(1<<start)][start]=Power;

 43     int res=-1;

 44     for(int i=0;i<(1<<state);i++){

 45         for(int j=0;j<state;j++){

 46             if((i&(1<<j))==0)continue;

 47             if(dp[i][j]<0)continue;

 48             if(((i&final_state)&final_state)==final_state)res=max(res,dp[i][j]);

 49             for(int k=0;k<state;k++){

 50                 if((i&(1<<k))||(j==k))continue;

 51                 if(dist[node[j].x][node[j].y][node[k].x][node[k].y]<0)continue;

 52                 if(dp[i][j]-dist[node[j].x][node[j].y][node[k].x][node[k].y]<0)continue;

 53                 dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]-dist[node[j].x][node[j].y][node[k].x][node[k].y]);

 54                 if(map[node[k].x][node[k].y]=='G')dp[i|(1<<k)][k]=Power;

 55             }

 56         }

 57     }

 58     return res>=0;

 59 }

 60 

 61 

 62 int main()

 63 {

 64     int low,high,mid,ans;

 65     while(~scanf("%d%d",&n,&m)){

 66         if(n==0&&m==0)break;

 67         state=0;

 68         final_state=0;

 69         for(int i=0;i<n;i++){

 70             scanf("%s",map[i]);

 71             for(int j=0;j<m;j++){

 72                 if(map[i][j]=='F'){

 73                     start=state;

 74                     node[state].x=i,node[state].y=j;

 75                     final_state|=(1<<state);

 76                     state++;

 77                 }else if(map[i][j]=='G'){

 78                     node[state].x=i,node[state++].y=j;

 79                 }else if(map[i][j]=='Y'){

 80                     node[state].x=i,node[state].y=j;

 81                     final_state|=(1<<state);

 82                     state++;

 83                 }

 84             }

 85         }

 86         memset(dist,-1,sizeof(dist));

 87         for(int i=0;i<state;i++){

 88             bfs(node[i]);

 89         }

 90         low=0,high=300,ans=-1;

 91         while(low<=high){

 92             mid=(low+high)>>1;

 93             if(Judge(mid)){

 94                 ans=mid;

 95                 high=mid-1;

 96             }else

 97                 low=mid+1;

 98         }

 99         printf("%d\n",ans);

100     }

101     return 0;

102 }

103 

104 

105         

106 

107                     
View Code

 

你可能感兴趣的:(HDU)