HDU 1044 Collect More Jewels(BFS+DFS)
来源:互联网 发布:2018php工作前景怎么样 编辑:程序博客网 时间:2024/05/26 02:18
HDU 1044 Collect More Jewels(BFS+DFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1044
题意:
给你一个R*C的棋盘迷宫,要求你在t时间走出迷宫且输出你能获得的最大珠宝价值和.
分析:
首先我们可以知道图中的有效点只有3种:起点,所有宝珠,终点.其中起点我们编号为0,珠宝编号为1到M,终点编号为M+1.
所以我们先用BFS求出以上任意两个有效点之间的距离,然后DFS从起点开始尝试一一走过每一个还没走到的有效点,只要时间不超过t即可.如果当前点是珠宝点,就把该价值加上,如果当前点是终点,就用当前所获得的价值和s更新ans.
不过代码中还有需要剪枝和注意的细节,需要仔细体会代码.
注意:DFS中不可以定序选取下一点,因为最优解可能必须先走B再走A. 很有可能不存在先A,再B,再C等的最优解.
AC代码:
#include<cstdio>#include<queue>#include<cstring>#include<algorithm>#include<ctype.h>using namespace std;const int maxn=50+10;int dr[]={-1,1,0,0};int dc[]={0,0,-1,1};int R,C,t,M;int sum,ans;//sum是所有珠宝价值和,ans是解char map[maxn][maxn];int abc[maxn][maxn];//abc[i][j]=x表第i个有效点到第j个有效点之间的距离,如果为0表示不存在路径int dist[maxn][maxn], vis1[maxn][maxn];//BFS时使用//注意dist[r][c]表示BFS中的id点到(r,c)的最短距离,其中id为0到M+1.而vis1[r][c]类似int vis2[maxn]; //DFS时使用int val[maxn];//宝珠的价值,宝珠从1到M编号void BFS(int r,int c,int id){ queue<int> Q; vis1[r][c]=1; dist[r][c]=0; Q.push(r*C+c); //错误1,这里及后面写成了r*R+c了 while(!Q.empty()) { int z=Q.front(); Q.pop(); int x=z/C, y=z%C; for(int d=0;d<4;d++) { int xx=x+dr[d], yy=y+dc[d]; if(xx<0||xx>=R||yy<0||yy>=C||map[xx][yy]=='*') continue; if(vis1[xx][yy]) continue; vis1[xx][yy]=1; dist[xx][yy]= dist[x][y]+1; if(map[xx][yy]=='@') abc[id][0] = dist[xx][yy]; else if(isalpha(map[xx][yy])) abc[id][map[xx][yy]-'A'+1] = dist[xx][yy]; else if(map[xx][yy]=='<') abc[id][M+1]=dist[xx][yy]; Q.push(xx*C+yy); } }}void dfs(int p,int s,int time)//当前在第p个有效点,拥有价值s的珠宝,花了time时间{ if(time>t || ans==sum) return; //剪枝,朝时了或已经得到最优解了 if(p==M+1 && s>ans) ans=s; //到达了终点且总价值s>ans,值得更新 else for(int i=1;i<=M+1;i++) { if(vis2[i]==1 || abc[p][i]==0) continue; //第i个有效点已经被走过或不存在从p到i的路径 vis2[i]=1; dfs(i,s+val[i],time+abc[p][i]); vis2[i]=0; }}int main(){ int T; scanf("%d",&T); for(int kase=1;kase<=T;kase++) { sum=0; memset(abc,0,sizeof(abc)); //错误2,忘记了对abs初始化 memset(vis2,0,sizeof(vis2)); scanf("%d%d%d%d",&C,&R,&t,&M); for(int i=1;i<=M;i++) scanf("%d",&val[i]), sum+=val[i]; val[0]=val[M+1]=0; for(int i=0;i<R;i++) scanf("%s",map[i]); for(int i=0;i<R;i++) for(int j=0;j<C;j++) { if(map[i][j]!='@'&&map[i][j]!='<'&&!isalpha(map[i][j])) continue;//非有效点 memset(vis1,0,sizeof(vis1)); memset(dist,0,sizeof(dist)); if(map[i][j]=='@') BFS(i,j,0); else if(isalpha(map[i][j])) BFS(i,j,map[i][j]-'A'+1); else if(map[i][j]=='<') BFS(i,j,M+1); } vis2[0]=1; ans=-1; dfs(0,0,0);//当前在0号点,处于0秒时间且已经获得价值0的珠宝 if(ans>=0) printf("Case %d:\nThe best score is %d.\n",kase,ans); else printf("Case %d:\nImpossible\n",kase); if(kase<T) puts(""); } return 0;}
0 0
- hdu 1044Collect More Jewels ( bfs + dfs )
- HDU-1044 Collect More Jewels BFS + DFS
- HDU 1044 Collect More Jewels(BFS+DFS)
- hdu 1044Collect More Jewels(bfs+dfs)
- HDU 1044 Collect More Jewels(BFS+DFS)
- hdu 1044 Collect More Jewels bfs+状态压缩/bfs+dfs
- HDU ACM 1044 Collect More Jewels BFS+DFS
- hdu 1044 Collect More Jewels(BFS+DFS)
- HDU 1044 Collect More Jewels 【经典BFS+DFS】
- HDU 1044 Collect More Jewels【BFS+DFS+建立距离图】
- HDU 1044 Collect More Jewels(BFS+DFS)
- HDOJ 1044 Collect More Jewels BFS+DFS
- hdu 1044 Collect More Jewels (两种解法 1.bfs+状压 2.bfs+dfs)
- hdoj 1044 Collect More Jewels(经典题 bfs+dfs)
- hdu1044+BFS+DFS+Collect More Jewels
- hdu1044 Collect More Jewels----BFS+DFS
- hdu(1044) Collect More Jewels
- HDU 1044 Collect More Jewels
- 栈之扩展操作
- ACM-ICPC XTCPC06比赛总结
- C语言的高级应用技巧
- Android - 文件操作
- 二进制的运算符
- HDU 1044 Collect More Jewels(BFS+DFS)
- hdu 2086 A1 = ?
- HDU 1242 Rescue (BFS+优先队列)
- start_kernel()分析(一)
- Java类的初始化过程
- 社区问答专家招奖征资源分享有内涵访顾伟
- 决定踏上程序员之路!
- 时序分析/约束(一):相关概念
- Longest Palindromic Substring