蓝桥杯 2014本科C++ B组 地宫取宝 DFS+记忆化搜索
历届试题 地宫取宝
时间限制:1.0s 内存限制:256.0MB
问题描述
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 2 2
1 2
2 1
样例输出
2
样例输入
2 3 2
1 2 3
2 1 5
样例输出
14
话说这个题目意图还是蛮明显的,深搜完后返回所有满足的解的个数,不过这个善意的题目,要想完全正确还是学需要在处理时注意很多方面。
首先,先来谈第一个问题,写出其状态转移方程,我们要求的解是从原点手握价值最大的宝物v开始经过不同的路径到终点获得K件宝物的路径总数,我们姑且将此状态记为
d(1,1,k(初始为0,还没拿宝贝),-1(此时手上没有宝物,值记为-1))
那么从此状态出发,可以将其转移为如下的决策

这里在补充说明用状态转移方程可以方便将原问题分解成若干个与原问题相同的子问题,且规模变小。
第二个问题,如果仅仅这样的话,必然存在重复计算的问题,为此必须要采取记忆化搜索的方式,对于已经计算过的结点保存其值,就这条题目而言,必须要用一个四维数组保存,因为它的状态跟位置,个数以及当前最大的宝物价值有关。当重复遍历这个结点时,直接传值。
第三个问题,细节决定成败!!
1.类型用long long稳妥,因为即使MOD了,但是如果两个数加起来还有可能超int。
2.我自己做的时候没注意的一个小错误,导致最后始终不对的疏忽。我错误的把r[MAXN][MAXN][15][15]的初始化为了0,这绝对不正确,因为有可能以某种方式走的状态就是无解,就是0,必须将初始值赋为-1。
3.对于有宝物的初始价值为-1,比较好的处理方式是,最后存放是第四维的下标后移一位
4.这里还要注意,k最多是13,不会超过这个值,所以第三维只要14就够了
其它的就看代码吧:
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 60
#define MOD %1000000007
using namespace std;
long long r[MAXN][MAXN][][];//保存状态
long long map[MAXN][MAXN];//初始地图
long long m,n,num;
long long dfs(long long i,long long j,long long k,long long v)
{
long long s=,t;
if(r[i][j][k][v+]!=-)
return r[i][j][k][v+];
if(i==m&&j==n)//到达终点
{
if(k==num)
{
r[m][n][k][v+]=;
return r[m][n][k][v+];
}
else if(k==num-&&map[m][n]>v)
{
r[m][n][k][v+]=;
return r[m][n][k][v+];
}
else
{
r[m][n][k][v+]=;
return r[m][n][k][v+];
}
}
else
{
if(map[i][j]>v)
{
t=map[i][j];
if(i+<=m)
s=(s+dfs(i+,j,k+,t)MOD+dfs(i+,j,k,v)MOD)MOD;
if(j+<=n)
s=(s+dfs(i,j+,k+,t)MOD+dfs(i,j+,k,v)MOD)MOD;
}
else
{
if(i+<=m)
s=(s+dfs(i+,j,k,v)MOD)MOD;
if(j+<=n)
s=(s+dfs(i,j+,k,v)MOD)MOD;
}
r[i][j][k][v+]=s MOD;
return r[i][j][k][v+];
}
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
memset(r,-,sizeof(r));
long long i,j,p,q;
cin>>m>>n>>num;
for(i=;i<=m;i++)
for(j=;j<=n;j++)
cin>>map[i][j];
dfs(,,,-);
cout<<r[][][][]<<endl;
return ;
}
蓝桥杯 2014本科C++ B组 地宫取宝 DFS+记忆化搜索的更多相关文章
- 蓝桥杯 2014本科C++ B组 奇怪的分式 暴力枚举
蓝桥杯 枚举 奇怪的分式 标题:奇怪的分式 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1 ...
- 蓝桥杯 2014本科C++ B组 李白打酒 三种实现方法 枚举/递归
标题:李白打酒 话说大诗人李白,一生好饮.幸好他从不开车. 一天,他提着酒壶,从家里出来,酒壶中有酒2斗.他边走边唱: 无事街上走,提壶去打酒. 逢店加一倍,遇花喝一斗. 这一路上,他一共遇到店5次, ...
- 蓝桥杯 2014本科C++ B组 六角填数 枚举排列
标题:六角填数 如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不要填 ...
- 第五届蓝桥杯C++B组 地宫取宝
代码: #include <bits/stdc++.h> using namespace std; #define ll long long const ll mod = 1e9 + 7; ...
- 【蓝桥杯真题】地宫取宝(搜索->记忆化搜索详解)
链接 [蓝桥杯][2014年第五届真题]地宫取宝 题目描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被 ...
- 问题 1436: 地宫取宝 (dp)
题目传送门 时间限制: 1Sec 内存限制: 128MB 提交: 423 解决: 94 题目描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标 ...
- 2014 蓝桥杯 预赛 c/c++ 本科B组 第九题:地宫取宝(12') [ dp ]
历届试题 地宫取宝 时间限制:1.0s 内存限制:256.0MB 锦囊1 锦囊2 锦囊3 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件 ...
- 地宫取宝|2014年蓝桥杯B组题解析第九题-fishers
地宫取宝 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...
- [蓝桥杯]2014蓝桥省赛B组题目及详解
/*——————————————————————————————————————————————————————————— [结果填空题]T1 题目:啤酒和饮料 啤酒每罐2.3元,饮料每罐1.9元.小 ...
随机推荐
- erlang 小程序:整数序列,搜索和为正的最长子序列
近期学习了一下erlang, 编了个小程序 算法例如以下: 把參数分为三个 当前位置的前子序列(Save)(比方 -5, 1,2,-1, _, ... ) 当前位置为_时, 前子序列就是 1,2,-1 ...
- javascript 判断字符串是否包换字符串
用"ghiahgiahgia".indexOf("hg"); 返回值>=0为包含,否则就是-1(不包含)
- python(28)- 面向对象练习Ⅱ
题目一:总结 1.什么是绑定到对象的方法,如何定义,如何调用,给谁用?有什么特性? 类内定义的函数,不经装饰器装饰,被实例化对象调用,会默认传入一个self参数,对象将会传递给self: 定义方式比较 ...
- Cocos2d-X中的粒子
Cocos2d-x引擎提供了强大的type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/particle-s ...
- 【每日Scrum】第五天(4.26) TD学生助手Sprint2站立会议
站立会议 组员 昨天 今天 困难 签到 刘铸辉 (组长) 今天增加了几个页面的子菜单,然后设计了几个要用的界面 今天和楠哥做了课程事件和日历表操作的例子,并尝试做时间表和日历表的数据库设计 安卓的数据 ...
- git操作演示
阶段一: git init git config --global user.email "you@example.com" git config --global user.na ...
- 分布式流媒体直播服务器系统 For Linux
在之前的一篇<基于Darwin实现的分布式流媒体直播服务器系统>中,我们配置了在Win32下面的流媒体直播系统,今天我们分享一下在Linux下面EasyDSS分布式直播服务器系统的配置. ...
- 让EasyDarwin只支持RTP over TCP传输
我们经常需要EasyDarwin服务器支持公网流媒体传输,但很多时候,播放器默认都是通过RTP over UDP的形式在RTSP SETUP中请求,往往都以在内网接收不到UDP数据失败结束,那么我们如 ...
- 九度OJ 1097:取中值 (中值)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5092 解决:1411 题目描述: 存在两组数组,和4个数字a,b,c,d,要求做如下操作,将第一个数组第a个数到第b个数,第二个数组的第c ...
- Golang RPC 性能测试
Golang RPC 性能测试 | KDF5000 http://kdf5000.com/2017/03/28/Golang-RPC-性能测试/