哈利波特假期回姨夫家的时候会把他的宝贝藏在地精银行,现在要偷他的宝贝,银行的房间分为可破坏与不可破坏两种,其实就是可到达与不可到达,然后给出哈利的k个宝贝放的位置,如果能全部拿到输出最小的步数,不能拿到则输出-1,用BFS搜索,最先搜到的肯定就是步数最小的,搜不到则输出-1.最近做的好多DP题都跟搜索有关系,看来还是多方面都得会才行啊。
#include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <algorithm> #include <cmath> #include <iomanip> #include <set> using namespace std; struct node { int x; int y; int bit; }bb[5];//结构体方便表示与储存 char s[101][101]; int map[101][101]; int dp[1<<4][101][101];//记录步数 int n,m,k; int dir[4][2]={{1,0},{0,-1},{-1,0},{0,1}};//方向数组 bool in(int x,int y)//判断是否越界 { if(x>=1&&x<=n&&y>=1&&y<=m) { return true; } return false; } int bfs(int x,int y) { queue<node> q; memset(dp,0,sizeof(dp)); node f; f.x=x; f.y=y; f.bit=0; int p=0; for(int i=0;i<k;i++) { if(f.x==bb[i].x&&f.y==bb[i].y) { p=i+1; break; } } if(p) { f.bit=f.bit|1<<(p-1); } q.push(f); //cout<<f.x<<" "<<f.y<<endl; while(!q.empty()) { node w=q.front(); //cout<<w.x<<" "<<w.y<<endl; q.pop(); if(w.bit==(1<<k)-1) { return dp[w.bit][w.x][w.y];//全部取完,跳出 } node e; for(int i=0;i<4;i++) { e.x=w.x+dir[i][0]; e.y=w.y+dir[i][1]; e.bit=w.bit; p=0; for(int j=0;j<k;j++) { if(e.x==bb[j].x&&e.y==bb[j].y) { p=j+1; break; } } if(p) { e.bit=w.bit|1<<(p-1);//修改二进制表示已取到 } if(in(e.x,e.y)&&map[e.x][e.y]&&!dp[e.bit][e.x][e.y])//!dp[e.bit][e.x][e.y]剪枝,因为每一格都可以走吗所以防止一直前后踏步导致爆掉 { dp[e.bit][e.x][e.y]=dp[w.bit][w.x][w.y]+1; q.push(e);//入队 //cout<<e.x<<" "<<e.y<<endl; } } } return -1; } int main() { int x,y; while(scanf("%d%d",&n,&m)!=EOF) { memset(map,0,sizeof(map));//标记是否可以通过 if(n==0&&m==0) { break; } for(int i=0;i<n;i++) { scanf("%s",s[i]); for(int j=0;j<m;j++) { if(s[i][j]=='@'||s[i][j]=='.') { map[i+1][j+1]=1; } if(s[i][j]=='@') { x=i+1; y=j+1; } } } scanf("%d",&k); for(int i=0;i<k;i++) { scanf("%d%d",&bb[i].x,&bb[i].y); } //cout<<x<<" "<<y<<endl; cout<<bfs(x,y)<<endl; } return 0; }
HDU-4771 Stealing Harry Potter's Precious 状压DP+BFS,布布扣,bubuko.com
HDU-4771 Stealing Harry Potter's Precious 状压DP+BFS
原文地址:http://blog.csdn.net/q295657451/article/details/38403419