5 5 GDDSS SSSFS SYGYS SGSYS SSYSS 0 0
4
这题做死人了……coding能力好差啊……突然发现……
这题题目意思是说有个机器人在F位置
Y表示开关
D表示障碍
G表示一次性充电器
机器人每次只能上下左右走,每走一步消耗一点电量,如果木有电量当然就走不了了,然后走到一次性充电器可以充满电,但是这个充电器就报废了(一次性的嘛),障碍是不能走的地方,问机器人遍历一次开关最少需要带电容量为多大的电池
把所有的G和Y找出来,然后做一次TSP即可,注意G可以不用完全遍历。
首先先找G和Y,再加上起点做一次BFS求两两之间的最短路,之后二分答案,对每个答案用状态dp判断是否能够遍历所有的Y。
送上代码
#include <stdio.h> #include <queue> #include <string.h> #include <algorithm> #define INF 99999999 using namespace std; typedef struct { int x,y; int val;//'G':1;'Y':2 int step; }point; int n,m,up; char map[20][20]; int bfs[20][20]; point hash[20]; int start[20]; queue <point> q; int vis[20][20]; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int dp[(1<<15)+2][16]; bool cmp(point a,point b) { return a.val<b.val; } int BFS(point a,point b) { point tag,tag1; int i; while(!q.empty()) { q.pop(); } a.step=0; q.push(a); memset(vis,0,sizeof(vis)); while(!q.empty()) { tag=q.front(); q.pop(); if (tag.x==b.x && tag.y==b.y) return tag.step; if (tag.x<0 || tag.x>=n || tag.y<0 || tag.y>=m) continue; if (vis[tag.x][tag.y]==1) continue; if (map[tag.x][tag.y]=='D') continue; vis[tag.x][tag.y]=1; tag1=tag; tag1.step++; for (i=0;i<4;i++) { tag1.x=tag.x+dx[i]; tag1.y=tag.y+dy[i]; q.push(tag1); } } return INF; } bool Check(int t) { int i,j,k,l,p; memset(dp,-1,sizeof(dp)); dp[0][0]=0; for (j=0;j<(1<<up);j++) { for (k=0;k<up;k++) { if (dp[j][k]==-1) continue; // printf("%d..%d..%d..\n",j,k,dp[j][k]); if (j==0) { for (l=0;l<up;l++) { if (t<start[l]) continue; if (hash[l].val==1) dp[1<<l][l]=t; else dp[1<<l][l]=t-start[l]; } continue; } for (l=0;l<up;l++) { if ((j & (1<<l))!=0) continue; p=(j | (1<<l)); if (bfs[k][l]>dp[j][k]) continue; if (hash[l].val==1) dp[p][l]=t; else dp[p][l]=max(dp[p][l],dp[j][k]-bfs[k][l]); } } } for (i=0;i<up;i++) { if (hash[i].val==2) break; } for (j=(1<<up)-(1<<i);j<(1<<up);j++) { for (k=0;k<up;k++) { // printf("%d...%d...%d\n",j,k,dp[j][k]); if (dp[j][k]>=0) return true; } } return false; } int main() { int i,j,l,r,ok,mid; point beg; while(1) { scanf("%d%d",&n,&m); if (n==0 && m==0) break; for (i=0;i<n;i++) { scanf("%s",map[i]); } up=0; for (i=0;i<n;i++) { for (j=0;j<m;j++) { if (map[i][j]=='G') { hash[up].x=i; hash[up].y=j; hash[up++].val=1; } if (map[i][j]=='Y') { hash[up].x=i; hash[up].y=j; hash[up++].val=2; } if (map[i][j]=='F') { beg.x=i; beg.y=j; } } } if (up==0) { printf("1\n"); continue; } ok=0; sort(hash,hash+up,cmp); for (i=0;i<up;i++) { for (j=i+1;j<up;j++) { bfs[i][j]=bfs[j][i]=BFS(hash[i],hash[j]); } start[i]=BFS(beg,hash[i]); } for (i=0;i<up;i++) { if (start[i]==INF && hash[i].val==2) break; } if (i<up) { printf("-1\n"); continue; } l=0; r=n*m; while(l<=r) { mid=(l+r)/2; // printf("%d..%d..%d\n",l,r,mid); if (Check(mid)==true) r=mid-1; else l=mid+1; } printf("%d\n",r+1); } return 0; }