链接

[蓝桥杯][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代码如下:

void dfs(int i,int j,int cnt,int max){if(cnt>k||i>n||j>m)return;if(i==n&&j==m){if(cnt==k||(cnt==k-1&&maze[i][j]>max))(++ans)%MOD;return;}dfs(i,j+1,cnt,max);dfs(i+1,j,cnt,max);if(maze[i][j]>max){dfs(i+1,j,cnt+1,maze[i][j]);dfs(i,j+1,cnt+1,maze[i][j]);}}

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

代码

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

完整代码

#include<iostream>
#include<cmath>
#include<sstream>
#include<cstring>
using namespace std;
const int MOD=1000000007;
const int N=55;
int maze[N][N];
int vis[N][N];int n,m,k;long long ans=0;int cache[N][N][13][14];
void dfs(int i,int j,int cnt,int max){if(cnt>k||i>n||j>m)return;if(i==n&&j==m){if(cnt==k||(cnt==k-1&&maze[i][j]>max))(++ans)%MOD;return;}dfs(i,j+1,cnt,max);dfs(i+1,j,cnt,max);if(maze[i][j]>max){dfs(i+1,j,cnt+1,maze[i][j]);dfs(i,j+1,cnt+1,maze[i][j]);}}
//  递归改记忆型递归并不复杂,由于存在重复计算的情况
//  重复计算,就是dfs的参数一样,也就是达到目前的状态可能有许多方式,运用记忆化搜索,对于重复的位置只计算一次。
//  所以用一个标记数组,数组的参数与dfs的参数相同
long long dfs2(int i,int j,int cnt,int max){//查缓存 if(cache[i][j][cnt][max+1]!=-1)return cache[i][j][cnt][max+1];long long ans=0;//记得一定是局部变量 if(cnt>k||i>n||j>m)return 0;if(i==n&&j==m){if(cnt==k||(cnt==k-1&&maze[i][j]>max))++ans;return ans;}ans+=dfs2(i,j+1,cnt,max);ans+=dfs2(i+1,j,cnt,max);if(maze[i][j]>max){ans+=dfs2(i+1,j,cnt+1,maze[i][j]);ans+=dfs2(i,j+1,cnt+1,maze[i][j]);}
//      在return之前一定写缓存
cache[i][j][cnt][max+1]=ans%MOD;return ans%MOD; }
int main(){cin>>n>>m>>k;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cin>>maze[i][j];}memset(cache,-1,sizeof(cache));
//  dfs(1,1,0,-1);cout<<dfs2(1,1,0,-1)<<endl;//由于max最开始的值为-1,由于数组中不能访问-1.,所以做一个技巧,max+1 return 0;
}

转载于:https://www.cnblogs.com/gzr2018/p/10459927.html

【蓝桥杯真题】地宫取宝(搜索-记忆化搜索详解)相关推荐

  1. [蓝桥杯][2014年第五届真题]地宫取宝(记忆化搜索)

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

  2. 【蓝桥杯】历届试题 地宫取宝(记忆化搜索、dfs、dp)

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

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

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

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

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

  5. [蓝桥杯][算法提高]和谐宿舍2(记忆化搜索)

    问题描述 我的某室友学过素描,墙上有n张他的作品.这些作品都是宽度为1,高度不定的矩形,从左到右排成一排,且底边在同一水平线上. 宿舍评比就要来了,为了及格,我们决定买不多于m块的矩形木板,把这些作品 ...

  6. 第五届蓝桥杯真题解析【JavaC组】

    第五届蓝桥杯真题解析[JavaC组] 业精于勤,荒于嬉:行成于思,毁于随.--韩愈 文章目录 ***第五届蓝桥杯真题解析[JavaC组]*** 前言 A:猜年龄 B:等额本金 C:猜字母 D:大衍数列 ...

  7. 第九届蓝桥杯真题解析JavaC组

    第九届蓝桥杯真题解析JavaC组 文章目录 ***第九届蓝桥杯真题解析JavaC组*** 前言 A.哪天回家 B.猴子分香蕉 C.字母阵列 D.第几个幸运数 E.书号验证 F.打印大X G.缩位求和 ...

  8. 蓝桥杯真题2017-2021

    刷完近几年真题,感觉理解完之后,拿奖问题不大,本人这次获得2022年蓝桥杯javaB组省一,以下是历年javaB组省赛题目. 文章目录 2017年真题 一.购物单 二.纸牌三角形 三.承压计算 四.魔 ...

  9. 购物单 蓝桥杯真题(EXCEL一分钟巧解)

    上文链接:蓝桥杯之猴子吃桃-递归极度简化(c++实现) 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促 ...

最新文章

  1. 【怒怼老乔】居然苹果手机IOS系统还不支持css3的transparent属性值,我去~~~~
  2. 优秀开发者和差的开发者之间区别
  3. 海豚php添加一行,添加表单项通用方法-海豚PHP1.0.6完全开发手册-基于ThinkPHP5.0.10的快速开发框架...
  4. 《OpenCV图像处理》——1.7 用户交互工具
  5. 无人再谈CV:计算机视觉公司的困境
  6. 翻译:Intel CPU架构的历史
  7. 【编程题目】寻找丑数
  8. jq 如何获取和当然元素相同类名的标签_JS/JQ基于localStorage的本地数据储存指南...
  9. 光敏传感器实验报告_光敏电阻传感器实验报告
  10. oracle系统卸载干净,完全卸载oracle|oracle卸载|彻底卸载oracle
  11. 服务器CRT显示不全,CRT显示器显示画面不正常常见原因揭密
  12. 你真的理解this吗
  13. ASP.NET——使用FileUpLoad服务器控件实现文件上传
  14. Remix-IDE安装开发环境与使用文档(Windows环境)
  15. Spring boot @Value 注入 boolean 设置默认值问题
  16. 广告dsp,ssp,adx
  17. django的update和create高级操作
  18. A-the Beatles
  19. 工作技术点小结_webank
  20. Hbuilder app开发之app启动图片

热门文章

  1. 对dropout的理解详细版
  2. JavaScript数据结构与算法——列表详解(上)
  3. 链接分析算法系列-机器学习排序
  4. 使用OpenCV画折线图
  5. VC维与DNN的Boundary
  6. word文档图标变成白纸_挽救你的文件 修复变成乱码的Word文档
  7. 四则运算题目生成程序
  8. JAVA实现N皇后问题(回溯法)
  9. 添加功能与测试点总结
  10. ubuntu下用命令行安装Qt