思路:

先用bfs求出入口,宝物,出口,两两之间的最短距离。

在用dfs搜索所有情况,求出从入口走到出口能获得的最大价值。

我们要解决几个问题:1、求入口到第一个取宝物的地方的最短距离

2、求第i个取宝物的地方到第i+1个取宝物的地方的最短距离

3、求第n个取宝物的地方到出口的最短距离

4、保证以上3点能在时间L内实现的情况下,取得的宝石价值最大

熟悉两种搜索的优缺点:

BFS: 对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元用来存储状态)。

DFS:对于解决遍历求和问题有效,对于问题搜索深度小的时候处理速度迅速,然而在深度很大的情况下效率不高

dfs剪枝:
1.step>time直接return。
2.ans==sum时就不用再搜了  因为已经到最大了。
3.如果搜到一个点,这个点以前已经搜过,而且现在到达这个点时珠宝价值比以前少而且走的步数却比以前多,就不用搜这个点了。
真是被自己傻到了 。。。花了一个小时写了一个代码如下,感觉自己真是太弱智了,居然放这么大的错误,忽略了两件宝物可以在一条路径上,所以 以后编程还是要考虑周全在下手 ,尤其是比赛的时候,一旦有大的漏洞,就会被 坑哭了。。。
错误代码:

#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"cmath"
#include"string"
#include"string.h"
#include"queue"
#include"stack"
#include"vector"
#define  mx 105
using namespace std;
int  g[mx][mx];
int value[mx][mx];//存放每个点的价值
int time[mx][mx];//存放每个点的时间
int M[mx];//存放宝物的价值
int h,w,m,l,sx,sy,ex,ey,maxvalue;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct node
{int x,y;int times;int  values;
};
bool judge1(int x,int y)//判断能不能走
{if(x>=0&&x<h&&y>=0&&y<w&&g[x][y]!=-1)return true;return false;
}
bool judge2(int x,int y,int v,int t)//判断应不应该走
{if(v>value[x][y]) return true;if(t<time[x][y]) return true;return false;
}
void bfs()
{queue<node>q;node cur,next;int i;cur.x=sx;cur.y=sy;cur.times=0;cur.values=0;q.push(cur);while(!q.empty()){cur=q.front();q.pop();if(cur.x==ex&&cur.y==ey&&cur.times<=l){if(maxvalue<cur.values) maxvalue=cur.values;}for(i=0;i<4;i++){next.x=cur.x+dir[i][0];next.y=cur.y+dir[i][1];if(judge1(next.x,next.y)){next.times=cur.times+1;next.values=cur.values+g[next.x][next.y];if(judge2(next.x,next.y,next.values,next.times)){q.push(next);time[next.x][next.y]=next.times;value[next.x][next.y]=next.values;g[next.x][next.y]=0;}}}}
}
int main()
{int i,j,t,cou=0;;char ch;cin>>t;while(t--){cou++;cin>>w>>h>>l>>m;for(i=0;i<m;i++) cin>>M[i];getchar();for(i=0;i<h;i++){for(j=0;j<w;j++){cin>>ch;switch(ch){case '*':g[i][j]=-1;break;case '.':g[i][j]=0;break;case '@':g[i][j]=0;sx=i;sy=j;break;case '<':g[i][j]=0;ex=i;ey=j;break;default: g[i][j]=M[ch-'0'-65];break;}}}memset(value,0,sizeof(value));for(i=0;i<h;i++)for(j=0;j<w;j++) time[i][j]=1000001;maxvalue=-1;bfs();cout<<"Case "<<cou<<":"<<endl;if(maxvalue>=0)cout<<"The best score is "<<maxvalue<<"."<<endl<<endl;else cout<<"Impossible"<<endl<<endl;}return 0;
}

View Code

在网上搜了一下别人的代码,大致就是先利用bfs构建一个隐氏图,然后再用dfs进行搜索,找到最大价值总和。

#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"cmath"
#include"string.h"
#include"string"
#include"queue"
#define mx 105
using namespace std;
char mp[mx][mx];
bool used[mx][mx];//标记bfs走过的路径
bool vis[mx];//标记 dfs走过的路径
int value[mx];//记录宝物的价值
int H,W,L,M,ans,sum;
int step[mx][mx];//记录每个位置的最小步骤
int dis[mx][mx];//记录出口、入口、宝物两两之间的最短距离
queue<int>q;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool judge(int x,int y)//判断该位置是否可走
{if(x>=0&&x<H&&y>=0&&y<W&&mp[x][y]!='*') return true;return false;
}
void bfs(int x1,int y1,int s)
{while(!q.empty()) q.pop();int dx,dy,i,u,x,y;memset(used,false,sizeof(used));memset(step,0,sizeof(step));u=x1*W+y1;q.push(u);used[x1][y1]=true;step[x1][y1]=0;while(!q.empty()){u=q.front();q.pop();x=u/W;y=u%W;for(i=0;i<4;i++){dx=x+dir[i][0];dy=y+dir[i][1];if(judge(dx,dy)){if(!used[dx][dy]){used[dx][dy]=true;step[dx][dy]=step[x][y]+1;if(mp[dx][dy]=='@')dis[s][0]=step[dx][dy];else if(mp[dx][dy]=='<')dis[s][M+1]=step[dx][dy];else if(mp[dx][dy]>='A'&&mp[dx][dy]<='J')dis[s][mp[dx][dy]-'A'+1]=step[dx][dy];q.push(dx*W+dy);}}}}
}
void dfs(int s,int val,int time)
{int i;if(time>L) return;if(ans==sum) return;if(s>M){if(val>ans)ans=val;return;}for(i=0;i<=M+1;i++){if(dis[s][i]==0||vis[i]) continue;vis[i]=true;dfs(i,value[i]+val,time+dis[s][i]);vis[i]=false;}
}
int main()
{int i,j,t,icase=0;cin>>t;while(t--){sum=0;ans=-1;memset(dis,0,sizeof(dis));//记得初始化disicase++;cin>>W>>H>>L>>M;for(i=1;i<=M;i++) {cin>>value[i];sum+=value[i];}for(i=0;i<H;i++) cin>>mp[i];value[0]=0;value[M+1]=0;for(i=0;i<H;i++){for(j=0;j<W;j++){if(mp[i][j]=='@') bfs(i,j,0);else if(mp[i][j]=='<')bfs(i,j,M+1);else if(mp[i][j]>='A'&&mp[i][j]<='J') bfs(i,j,mp[i][j]-'A'+1);}}memset(vis,false,sizeof(vis));vis[0]=true;dfs(0,0,0);cout<<"Case "<<icase<<":"<<endl;if(ans>0)cout<<"The best score is "<<ans<<"."<<endl;else  cout<<"Impossible"<<endl;if(t) cout<<endl;}
}

View Code

转载于:https://www.cnblogs.com/acm-jing/p/4433357.html

hdu Collect More Jewels相关推荐

  1. Java入参关键字_Java基础17-成员变量、return关键字和多参方法

    1.成员变量 在类中声明的变量为成员变量 //Dog类 class Dog{ String name;//成员变量 } public class Test1{ public static void m ...

  2. 杭电OJ分类题目(1)

    原题出处:HDOJ Problem Index by Type,http://acm.hdu.edu.cn/typeclass.php 杭电OJ分类题目(1) HDU Introduction HDU ...

  3. 杭电1044java实现dfs bfs

    Collect More Jewels 问题描述 它写在"夫人的书:创世之后,残酷的神摩洛克反抗了造物主马尔杜克的权威.摩尔从马尔杜克那里偷走了众神中所有神器中最强大的一件,也就是叶多尔的护 ...

  4. HDU-基础搜索总结

    Dfs: 1241 Oil Deposits 题解:https://blog.csdn.net/HeZhiYing_/article/details/81053035 1016 Prime Ring ...

  5. HDU Problem 2062 Bone Collector【01背包】

    Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  6. hdu 2602 Bone Collector(01背包)模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Bone Collector Time Limit: 2000/1000 MS (Java/Ot ...

  7. HDU 2602.Bone Collector-动态规划0-1背包

    Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  8. HDU 5573 Binary Tree 构造

    Binary Tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5573 Description The Old Frog King lives ...

  9. HDU - 1982 Kaitou Kid - The Phantom Thief

    HDU - 1982 Kaitou Kid - The Phantom Thief 传送门 问题描述: Do you know Kaitou Kid? In the legend, Kaitou Ki ...

  10. hdu 3635 Dragon Balls 龙珠 带权并查集

    每次移动都是一个群龙珠移动到另一群龙珠所在的城市里面.所以这两个城市之间都不会空. 用并查集表示,每一个祖先节点的序号和他们所在城市的序号相同. 无论路径如何压缩,子结点的移动次数=父节点的移动次数+ ...

最新文章

  1. [leetcode] 数字游戏
  2. ASP.NET 页生命周期概述
  3. keras中lstm参数_如何使用Keras为自定义NER构建深度神经网络
  4. php yield 个人小解_php 技术 yield 问题
  5. udp 传输文件 java_Java 网络编程 之 UDP 文件传输
  6. 开始时间小于 结束时间 js_DNF分享红包开始及结束时间 红包有什么奖励相关介绍...
  7. 数据处理-Batch Normalization
  8. nginx 替换返回请求中的字符
  9. jpa 数据库方言_使用Hibernate和Oracle 10g方言,如何用JPA生成我的id?
  10. Permission Denial: requires android.permission.CHANGE_CONFIGURATION
  11. HTML 5 span 标签
  12. python3之urllib代理池
  13. zynq以太网官网例子调试
  14. 字典爆破php,密码字典 渗透测试字典 爆破字典
  15. linux设置usb选择性暂停,USB大容量存储设备无法启动的解决方法
  16. c++控制台游戏-小镇物语正式版 V1.7.2 [可存档!!!]
  17. Centos7值得收藏的网站
  18. uni-app开发APP上架Apple Store流程记录
  19. Android插件化初识
  20. 测试个人禀赋的软件,中医体质自测,个人体质测试,体质健康测试,测试自己的体质...

热门文章

  1. 金蝶移动bos开发教程_移动安全(四)|NDK开发教程_JavaToC
  2. laydate组件 无法传值_Vue组件间通信几种方式,你用哪种?【实践】
  3. markdown html 注释,在 Markdown 注释
  4. canal与mysql高可用_canal 高可用介绍(4)
  5. java参数化比特值,在Java中使用泛型的可选参数化
  6. 多线程中的互斥控制程序代码_互斥锁解决 Python 中多线程共享全局变量的问题...
  7. python随机数产生--random常用功能
  8. microsoft visual c++与microsoft visual net 版本对应关系
  9. 使用锚标记返回网页顶部的方法
  10. MySQL之 视图,触发器,事物,存储过程,函数(Day48)