问题描述
  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
 
暴力dfs会超时,可以dp或者记忆化搜索....理解可以...自己写可能就....gg了...
这样的话,感觉还是记忆化搜索更萌一些,因为不用考虑那么多边界...
思路见代码.
dp:
/*
蓝桥杯历届试题地宫寻宝 dp
状态:dp[i][j][num][val] 表示从起点(1, 1)走到(i, j), 已经取了num个宝物,最大价值是val 的方案数。
初态:dp[1][1][0][0] = 1; dp[1][1][1][mp[1][1]] = 1;
转移方程:由上方或者左方的格子转移而来,详见代码;
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std; #define mod 1000000007
int dp[55][55][15][15];
int mp[55][55]; int main() {
int n, m, k;
while(~scanf("%d%d%d", &n, &m, &k)) {
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
scanf("%d", &mp[i][j]);
}
} memset(dp, 0, sizeof(dp));
dp[1][1][0][0] = 1;
dp[1][1][1][mp[1][1]] = 1; for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
dp[i][j][0][0] += (dp[i-1][j][0][0] + dp[i][j-1][0][0]);
dp[i][j][0][0] %= mod;
for (int num=1; num<=k; ++num) {
for (int val=0; val<=12; ++val) {
dp[i][j][num][val] += (dp[i-1][j][num][val] + dp[i][j-1][num][val]);
dp[i][j][num][val] %= mod;
}
if (num == 1) {
dp[i][j][1][mp[i][j]] += dp[i-1][j][0][0];
dp[i][j][1][mp[i][j]] %= mod;
dp[i][j][1][mp[i][j]] += dp[i][j-1][0][0];
dp[i][j][1][mp[i][j]] %= mod;
}
else {
for (int t=0; t<mp[i][j]; ++t) {
dp[i][j][num][mp[i][j]] += dp[i-1][j][num-1][t];
dp[i][j][num][mp[i][j]] %= mod;
dp[i][j][num][mp[i][j]] += dp[i][j-1][num-1][t];
dp[i][j][num][mp[i][j]] %= mod;
}
}
}
}
} int ans = 0;
for (int i=0; i<=12; ++i) {
ans += dp[n][m][k][i];
ans %= mod;
}
printf("%d\n", ans);
}
return 0;
}

记忆化搜索:

/*
蓝桥杯历届试题 地宫取宝 dp[i][j][num][k] 表示到位置(i, j)时, 取了第num个宝藏,最大宝藏值是k时,
能到终点的路线方案数。 dfs超时。
记忆化搜索...
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define mod 1000000007 int dp[55][55][15][15];
int n, m, k;
int mp[55][55]; int dfs(int nowx, int nowy, int cnt, int nowMax) {
if (dp[nowx][nowy][cnt][nowMax+1] != -1) {
return dp[nowx][nowy][cnt][nowMax+1];
}
int ans = 0;
if (nowx == n-1 && nowy == m-1) {
if (mp[nowx][nowy] > nowMax) {
if (cnt == k || cnt == k-1)
ans++;
ans %= mod;
}
else if (cnt == k) ans++;
ans %= mod;
return dp[nowx][nowy][cnt][nowMax+1] = ans;
} if (nowx+1 < n) {
if (mp[nowx][nowy] > nowMax) {
ans += dfs(nowx+1, nowy, cnt+1, mp[nowx][nowy]);
ans %= mod;
}
ans += dfs(nowx+1, nowy, cnt, nowMax);
ans %= mod;
}
if (nowy+1 < m) {
if (mp[nowx][nowy] > nowMax) {
ans += dfs(nowx, nowy+1, cnt+1, mp[nowx][nowy]);
ans %= mod;
}
ans += dfs(nowx, nowy+1, cnt, nowMax);
ans %= mod;
}
return dp[nowx][nowy][cnt][nowMax+1] = ans;
} int main() {
while(~scanf("%d%d%d", &n, &m, &k)) {
memset(dp, -1, sizeof(dp));
for (int i=0; i<n; ++i) {
for (int j=0; j<m; ++j) {
scanf("%d", &mp[i][j]);
}
}
int ans = dfs(0, 0, 0, -1);
printf("%d\n", ans);
}
return 0;
}

  

蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索的更多相关文章

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

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

  2. 算法笔记_174:历届试题 地宫取宝(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明 ...

  3. 【bzoj1415】【聪聪和可可】期望dp(记忆化搜索)+最短路

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=57148470 Descrition 首先很明显是 ...

  4. 二进制数(dp,记忆化搜索)

    二进制数(dp,记忆化搜索) 给定k个<=1e6的正整数x(k不大于10),问最小的,能被x整除且只由01组成的数. 首先,dp很好写.用\(f[i][j]\)表示i位01串,模ki的值是j的数 ...

  5. poj1179 区间dp(记忆化搜索写法)有巨坑!

    http://poj.org/problem?id=1179 Description Polygon is a game for one player that starts on a polygon ...

  6. 2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)

    心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起“唱” ...

  7. 【BZOJ3769】spoj 8549 BST again DP(记忆化搜索?)

    [BZOJ3769]spoj 8549 BST again Description 求有多少棵大小为n的深度为h的二叉树.(树根深度为0:左右子树有别:答案对1000000007取模) Input 第 ...

  8. HDU 3652 B-number(数位dp&amp;记忆化搜索)

    题目链接:[kuangbin带你飞]专题十五 数位DP G - B-number 题意 求1-n的范围里含有13且能被13整除的数字的个数. 思路 首先,了解这样一个式子:a%m == ((b%m)* ...

  9. 【CF607B】Zuma——区间dp(记忆化搜索/递推)

    以下是从中文翻译成人话的题面: 给定一个长度小于等于500的序列,每个数字代表一个颜色,每次可以消掉一个回文串,问最多消几次可以消完? (7.16) 这个题从洛谷pend回来以后显示有103个测试点( ...

随机推荐

  1. ACDC

    acdc dcdc电源模块中大功率一般都是开关电源模式的,所以一般输入都是一个较宽的电源范围,体积也相对于变压器要小一些,效率高一些,但是纹波会偏大一些,如何选择就要看电路的需求来选择相应的方案

  2. HDU-4521 小明系列问题——小明序列 间隔限制最长上升子序列

    题意:给定一个长度为N的序列,现在要求给出一个最长的序列满足序列中的元素严格上升并且相邻两个数字的下标间隔要严格大于d. 分析: 1.线段树 由于给定的元素的取值范围为0-10^5,因此维护一棵线段树 ...

  3. RTSP协议、RTMP协议、HTTP协议的区别

    理论上RTSP RTMPHTTP都可以做直播和点播,但一般做直播用RTSP RTMP,做点播用HTTP.做视频会议的时候原来用SIP协议,现在基本上被RTMP协议取代了. RTSP. RTMP.HTT ...

  4. thinkphp3.2+PHPExcel导出查询数据到excel表格的实例

    首先下载PHPExcel插件,我们需要把PHPExcel.php和PHPExcel文件夹放到D:\XAMPP\htdocs\fsxb\ThinkPHP\Library\Vendor\PHPExcel目 ...

  5. (三)VLAN基本概念

  6. ios中javascript直接调用oc代码而非通过改变url回调方式(转)

    之前一个ios项目中,需要通过UIWebview来打开一个静态页面,并在静态页面中 调用相关object-c代码. 一.以前使用js调用object-c的方法 关于如何使用javascript调用ob ...

  7. IIS_各种问题

    IIS7中默认是已经加载了脚本映射处理.但今天装了个WIN7,装好IIS后却发现没有.于是手动去这安装,在添加html映射时提示:模块列表中必须要有IsapiModule或cgiModule 因为 I ...

  8. 转! java 中“==” 与“ .equals ”比较

    在java程序设计中,经常需要比较两个变量值是否相等.例如1.简单数据类型比较a = 10;b = 10;if(a == b){//写要执行的代码}2.引用数据类型比较ClassA a = new C ...

  9. WebDriver 在使用 CSS Selector 与 XPath 在查找元素时如何取舍

    开发在做Web系统时,用的是css div划分层,使用jQuery 选取元素.

  10. Linux命令行下编译Android NDK的示例代码

    这几天琢磨写一个Android的Runtime用来加速HTML5 Canvas,让GameBuilder+CanTK 不但开发速度快,运行速度也能接近原生应用.所以花了点时间研究 Android ND ...