您的位置:首页 > 其它

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

2014-05-26 18:05 375 查看
题目链接: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: