链接

[蓝桥杯][2014年第五届真题]地宫取宝

题目描述

X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。

地宫的入口在左上角,出口在右下角。

小明被带到地宫的入口,国王要求他只能向右或向下行走。

走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。

当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。

请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

输入

输入一行3个整数,用空格分开:n m k (1< =n,m< =50, 1< =k< =12)

接下来有 n 行数据,每行有 m 个整数 Ci (0< =Ci< =12)代表这个格子上的宝物的价值。

输出

要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。

样例输入

2 3 2

1 2 3

2 1 5

样例输出

14

思路

这个题目分析题意可以得到是一个dfs递归的题目,因为要搜索出每一种可能的情况。并且这个问题不需要回溯(只是在地图上有两个方向可以选择,并且可以选择是否拾起物体,回溯是不取这个物体,这个物体需要另做他用,这个问题不需要考虑)。

接下来就是如何设计这个dfs。

1.首先考虑递归参数。当前走到的地图的位置(i,j),当前选择出的物品的数目cnt,当前的最大物品的质量max。

2.递归出口是走到了地图的出口,如果当前物品数量等于k,ans++,如果当前的物品数量等于k-1并且最后一个物品的重量大于max,ans++。另外一个递归出口是走出边际和选择的物品数量大于k。

dfs代码如下:

  1. void dfs(int i,int j,int cnt,int max){
  2. if(cnt>k||i>n||j>m)return;
  3. if(i==n&&j==m){
  4. if(cnt==k||(cnt==k-1&&maze[i][j]>max))(++ans)%MOD;
  5. return;
  6. }
  7. dfs(i,j+1,cnt,max);
  8. dfs(i+1,j,cnt,max);
  9. if(maze[i][j]>max){
  10. dfs(i+1,j,cnt+1,maze[i][j]);
  11. dfs(i,j+1,cnt+1,maze[i][j]);
  12. }
  13. }

这样会超时,因为在每一点可以选择的方案是2 or 4,这是一个指数级别搜索量。考虑到到达某一个点会有多种方案并且他们的状态是相同的,所以之前的方案存在重复计算,应该设计记忆型搜索,记忆递归函数应该返回一个值。

代码

  1. // 递归改记忆型递归并不复杂,由于存在重复计算的情况
  2. // 重复计算,就是dfs的参数一样,也就是达到目前的状态可能有许多方式,运用记忆化搜索,对于重复的位置只计算一次。
  3. // 所以用一个标记数组,数组的参数与dfs的参数相同
  4. long long dfs2(int i,int j,int cnt,int max){
  5. //查缓存
  6. if(cache[i][j][cnt][max+1]!=-1)return cache[i][j][cnt][max+1];
  7. long long ans=0;//记得一定是局部变量
  8. if(cnt>k||i>n||j>m)return 0;
  9. if(i==n&&j==m){
  10. if(cnt==k||(cnt==k-1&&maze[i][j]>max))++ans;
  11. return ans;
  12. }
  13. ans+=dfs2(i,j+1,cnt,max);
  14. ans+=dfs2(i+1,j,cnt,max);
  15. if(maze[i][j]>max){
  16. ans+=dfs2(i+1,j,cnt+1,maze[i][j]);
  17. ans+=dfs2(i,j+1,cnt+1,maze[i][j]);
  18. }
  19. // 在return之前一定写缓存
  20. cache[i][j][cnt][max+1]=ans%MOD;
  21. return ans%MOD;
  22. }

完整代码

  1. #include<iostream>
  2. #include<cmath>
  3. #include<sstream>
  4. #include<cstring>
  5. using namespace std;
  6. const int MOD=1000000007;
  7. const int N=55;
  8. int maze[N][N];
  9. int vis[N][N];
  10. int n,m,k;
  11. long long ans=0;
  12. int cache[N][N][13][14];
  13. void dfs(int i,int j,int cnt,int max){
  14. if(cnt>k||i>n||j>m)return;
  15. if(i==n&&j==m){
  16. if(cnt==k||(cnt==k-1&&maze[i][j]>max))(++ans)%MOD;
  17. return;
  18. }
  19. dfs(i,j+1,cnt,max);
  20. dfs(i+1,j,cnt,max);
  21. if(maze[i][j]>max){
  22. dfs(i+1,j,cnt+1,maze[i][j]);
  23. dfs(i,j+1,cnt+1,maze[i][j]);
  24. }
  25. }
  26. // 递归改记忆型递归并不复杂,由于存在重复计算的情况
  27. // 重复计算,就是dfs的参数一样,也就是达到目前的状态可能有许多方式,运用记忆化搜索,对于重复的位置只计算一次。
  28. // 所以用一个标记数组,数组的参数与dfs的参数相同
  29. long long dfs2(int i,int j,int cnt,int max){
  30. //查缓存
  31. if(cache[i][j][cnt][max+1]!=-1)return cache[i][j][cnt][max+1];
  32. long long ans=0;//记得一定是局部变量
  33. if(cnt>k||i>n||j>m)return 0;
  34. if(i==n&&j==m){
  35. if(cnt==k||(cnt==k-1&&maze[i][j]>max))++ans;
  36. return ans;
  37. }
  38. ans+=dfs2(i,j+1,cnt,max);
  39. ans+=dfs2(i+1,j,cnt,max);
  40. if(maze[i][j]>max){
  41. ans+=dfs2(i+1,j,cnt+1,maze[i][j]);
  42. ans+=dfs2(i,j+1,cnt+1,maze[i][j]);
  43. }
  44. // 在return之前一定写缓存
  45. cache[i][j][cnt][max+1]=ans%MOD;
  46. return ans%MOD;
  47. }
  48. int main(){
  49. cin>>n>>m>>k;
  50. for(int i=1;i<=n;i++)
  51. for(int j=1;j<=m;j++){
  52. cin>>maze[i][j];
  53. }
  54. memset(cache,-1,sizeof(cache));
  55. // dfs(1,1,0,-1);
  56. cout<<dfs2(1,1,0,-1)<<endl;
  57. //由于max最开始的值为-1,由于数组中不能访问-1.,所以做一个技巧,max+1
  58. return 0;
  59. }

【蓝桥杯真题】地宫取宝(搜索->记忆化搜索详解)的更多相关文章

  1. 蓝桥杯 2014本科C++ B组 地宫取宝 DFS+记忆化搜索

    历届试题 地宫取宝   时间限制:1.0s   内存限制:256.0MB 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角 ...

  2. 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  3. Java实现 蓝桥杯 历届试题 地宫取宝

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  4. 2015 UESTC 搜索专题B题 邱老师降临小行星 记忆化搜索

    邱老师降临小行星 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Des ...

  5. skiing(搜索+记忆化搜索)

    skiing 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当 ...

  6. P4363 [九省联考2018]一双木棋chess(对抗搜索+记忆化搜索)

    传送门 这对抗搜索是个啥玩意儿…… 首先可以发现每一行的棋子数都不小于下一行,且局面可由每一行的棋子数唯一表示,那么用一个m+1进制数来表示当前局面,用longlong存,开map记忆化搜索 然后时间 ...

  7. CodeForces1249B1/B2-Books Exchange-dfs-一般搜索+记忆化搜索

    一般搜索 注意:一般定义成void Books Exchange (easy version)  CodeForces - 1249B2 The only difference between eas ...

  8. Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)

    887. 鸡蛋掉落 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 < ...

  9. bfs记录路径,蓝桥杯真题

    题意:在01矩阵中,找到一条从入口到终点的最短路径,并且打印这条路径. 题目链接:http://lx.lanqiao.cn/problem.page?gpid=T291 #include<ios ...

随机推荐

  1. Codeforces 1097G

    根本想不到 CF1097G 题意 给出一棵树,定义f(S)为用最少的边连通点集$ S$的边数 求$ \sum\limits f(S)^k$ $ n \leq 10^5 k \leq 200$ 题解 假 ...

  2. Tomcat zabbix监控、jmx监控、zabbix_java_gateway

    几种方式监控tomcat,如标题. 下面就是参考的网上的连接.自己可以试一下. 由于牵扯到jvm的很多东西, 在这里就只是粘贴处连接参考. http://www.cnblogs.com/chrisDu ...

  3. Django ----- app 和 ORM的操作和介绍

    创建APP ORM 介绍 ORM的操作 说明一下 GET 和 POST 的区别: , GET ①获取一个页面 ②提交数据 数据显示在URL ?user=alex&pwd=alexdsb ,PO ...

  4. 【原创】大叔经验分享(43)logstash设置jdbc_default_timezone后报错

    logstash6.6.0-6.6.2版本使用jdbc input plugin时如果设置了jdbc_default_timezone,会报错: { 2012 rufus-scheduler inte ...

  5. nginx——location匹配流程图

    location匹配流程图 location理解 1.收到url请求后,nginx首先进行精确匹配(有“=”的为精确匹配),如果匹配成功,则直接返回精确匹配结果,如果没有命中则会继续向下进行普通匹配 ...

  6. Python学习笔记七

    面向对象编程 面向对象的特性如下: 类:具有相同属性和方法的一类事物,成为类. 对象:类的实例化后的结果,一个类可以实例化多个对象,每个对象也可以不同的属性. 封装:在类中对数据的赋值,类里面包含着类 ...

  7. ssh项目问题01,为创建数据库抛出的异常

    框架什么都搭建好了,但是一直抛出如图问题,网上资料很多让你设置时间之类的,也设置了还是继续抛异常,最后带我的师傅说没有创建数据库,我都要郁闷死了,网上那么多,很多写的都不能解决问题,还乱写,浪费别人时 ...

  8. Spark之join、leftOuterJoin、rightOuterJoin及fullOuterJoin

    Spark的join与mysql的join类似,mysql的join是将表与表之间连接查询,spark中join是将RDD数据集进行连接,Spark主要有join.leftOuterJoin.righ ...

  9. 自学华为IoT物联网_07 物联网安全

    点击返回自学华为IoT物流网 自学华为IoT物联网_07 物联网安全 1. 物联网安全的事件 事件1: 特斯拉事件 车载终端被入侵,通过CAN总线命令可远程控制车辆启停: 本地关键信息存储未做保护,印 ...

  10. [Doc]MongoDB用户创建与启用access-control

    文档链接:https://docs.mongodb.com/manual/tutorial/enable-authentication/ Pre 个人总感觉数据库的文档结构不太友好, 不太解决问题.以 ...