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