博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
历届试题 地宫取宝 记忆化搜索
阅读量:5272 次
发布时间:2019-06-14

本文共 2265 字,大约阅读时间需要 7 分钟。

    思路:状态d(x, y, k, max_num)表示当前已经走到坐标(x, y),拿到了k个宝物,宝物的最大值是max_num。

  1、如果当前点宝物的值等于max_num,那么他可以选择拿取当前宝物,那么下个状态就是d(x, y-1, k-1, w),d(x-1, y, k-1, w),0 <= w < max_num;

  2、不管当前宝物是什么情况,都不拿当前宝物,一直向下搜索,那么下个状态就是d(x, y-1, k,  max_num),d(x-1, y, k-1, max_num);

注意:第一种状态转移,可能会出现k==0的情况,此时可能会转移到多个k==0,max_num会有多个值,就存在重复计算,应该特殊处理一下。

  状态转移:

for(int j = 0; j < 2; ++j) {		int px = x + dx[j], py = y + dy[j];		if(px < 0 || py < 0) continue;		//拿取当前点宝物		if(a[x][y] == max_num)  {			if(cnt > 1) for(int i = 0; i < max_num; ++i) {				ans += dfs(px, py, cnt-1, i); 				ans %= mod;			}			else if(cnt == 1) ans += dfs(px, py, 0, 0);		}		//不拿取当前宝物		ans += dfs(px, py, cnt, max_num); 		ans %= mod;	}	return ans;
边界

if(x == 0 && y == 0) {		if(cnt == 0) return ans = 1;		if(cnt == 1 && max_num == a[x][y]) return ans = 1;		return ans = 0;	}
AC代码

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000") #define eps 1e-10#define inf 0x3f3f3f3f#define PI pair
typedef long long LL;const int maxn = 50 + 2, mod = 1000000007;int d[maxn][maxn][14][14], a[maxn][maxn];int n, m, k;const int dx[] = {0, -1};const int dy[] = {-1, 0};int dfs(int x, int y, int cnt, int max_num) { if(cnt < 0) return 0; int &ans = d[x][y][cnt][max_num]; if(ans != -1) return ans; ans = 0; //边界 if(x == 0 && y == 0) { if(cnt == 0) return ans = 1; if(cnt == 1 && max_num == a[x][y]) return ans = 1; return ans = 0; } for(int j = 0; j < 2; ++j) { int px = x + dx[j], py = y + dy[j]; if(px < 0 || py < 0) continue; //拿取当前点宝物 if(a[x][y] == max_num) { if(cnt > 1) for(int i = 0; i < max_num; ++i) { ans += dfs(px, py, cnt-1, i); ans %= mod; } else if(cnt == 1) ans += dfs(px, py, 0, 0); } //不拿取当前宝物 ans += dfs(px, py, cnt, max_num); ans %= mod; } return ans;}int main() { while(scanf("%d%d%d", &n, &m, &k) == 3) { memset(d, -1, sizeof(d)); for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) scanf("%d", &a[i][j]); int ans = 0; for(int i = 0; i < 13; ++i) { ans += dfs(n-1, m-1, k, i); ans %= mod; } printf("%d\n", ans); } return 0;}
如有不当之处欢迎指出!

 

转载于:https://www.cnblogs.com/flyawayl/p/8305370.html

你可能感兴趣的文章
Redis系统学习 二、数据结构
查看>>
(二)数据加密技术
查看>>
Iptables和Firewall-selinux
查看>>
C#设置程序自启动
查看>>
Hadoop基准测试(一)
查看>>
Linux下解压缩文件命令总结
查看>>
通过cookie验证用户登录
查看>>
2016012083+小学四则运算练习软件项目报告
查看>>
python操作MongoDB
查看>>
python字节码和机器码区别
查看>>
单点登录原理与简单实现
查看>>
如何选择做网站的公司
查看>>
Jquery 自定义插件写法(示例)
查看>>
JavaScript 变量,数据类型
查看>>
BootStrap引入不显示效果
查看>>
关于for循环的几个小练习,例如奇数偶数,阶乘,求和等
查看>>
Tomcat 配置 默认应用 (去掉项目名称、移除项目名称)
查看>>
敏捷软件需求阅读笔记01
查看>>
swf
查看>>
SolidWorks242个使用技巧
查看>>