专栏文章

题解:P8612 [蓝桥杯 2014 省 AB] 地宫取宝

P8612题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipvpays
此快照首次捕获于
2025/12/03 18:43
3 个月前
此快照最后确认于
2025/12/03 18:43
3 个月前
查看原文

分析

nn,mm 的值都不大,考虑搜索。
但是仔细一想好像会超时,怎么办呢,我们会发现我们重复计算了很多次一样的地方,那我们考虑吧每一次计算记录下来,下次再走到这个点直接用计算过的值,通过记录下所要的答案加快搜索效率就是 记忆化搜索

接下来我们考虑记录一个值需要考虑什么标记
  • 横纵坐标 xxyy 是一定的
  • 当前的最大价值 valval
  • 当前的宝物数 numnum
考虑清楚这些,那我们就可以写代码了。

特别提醒

  1. cc 的值是大于等于 0,那我们的 valval 要从 - 1 开始。
  2. 在计算完每一次递归后再取模,否则会影响 markmark 数组的记录。
  3. longlong longlong

代码奉上...
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=1e9+7;
int n,m,k,a[55][55],mark[55][55][15][15];
int dfs(int x,int y,int val,int num){
	if(x>n||y>m) return 0;
	if(mark[x][y][val+1][num]!=-1) return mark[x][y][val+1][num];
	int tmp=0;
	if(x==n&&y==m){
		if(num==k||num==k-1&&a[x][y]>val)
			tmp++;
	}else{
		tmp+=dfs(x+1,y,val,num);
		tmp+=dfs(x,y+1,val,num);
		if(a[x][y]>val){
			tmp+=dfs(x+1,y,a[x][y],num+1);
			tmp+=dfs(x,y+1,a[x][y],num+1);		
		}		
	}
	mark[x][y][val+1][num]=tmp%inf;
	return mark[x][y][val+1][num];
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);	
	cin>>n>>m>>k;
	memset(mark,-1,sizeof(mark));
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	cout<<dfs(1,1,-1,0);
	return 0;
}


评论

0 条评论,欢迎与作者交流。

正在加载评论...