原题链接:蓝桥杯2014年第五届真题-地宫取宝
解题思路:1.明显看出是一个dfs的题,暴力搜索各种路径 2.注意如果只用dfs会超时 3.所以要记忆走过的路径,二者集合起来即为 记忆化搜索!
注意事项:1.这题不仅要搜索,搜索中还得判断是否要拿走宝物,所以是个带参判断的搜索,宝物的价值即为需要考虑的参数。 2.记得用memset()来初始化数组为-1 3.由于宝物可能为0,max初始为-1,dp中要max+1
参考代码:
#include<iostream>
#define N 1000000007
#include<cstring>
using namespace std;
int n,m,k;
int mapvalue[51][51];
int dp[55][55][15][15];//动态规划路径
int dfs(int x,int y,int num,int maxv){
//判断路径有没走过
if(dp[x][y][num][maxv+1]!=-1)
return dp[x][y][num][maxv+1]; //走过就用统计过的路径(“记忆”的部分)
if(x==n&&y==m){ //走到了右下角
//分拿走或者不拿走右下角那个宝藏,都是一种方案
if(num==k||(num==k-1&&maxv<mapvalue[x][y]))
return dp[x][y][num][maxv+1]=1;
else return dp[x][y][num][maxv+1]=0;// 否则失败
}
//统计路径方案
long long s=0;
//向下深搜,分取或者不取这个宝物,由宝物价值判断
if(x+1<=n){ //向下控制不出界限
if(maxv<mapvalue[x][y])
s+=dfs(x+1,y,num+1,mapvalue[x][y]);
s+=dfs(x+1,y,num,maxv);//也可以不取
}
//向右深搜 分取或者不取这个宝物,由宝物价值判断
if(y+1<=m){ //向下控制不出界
if(maxv<mapvalue[x][y])
s+=dfs(x,y+1,num+1,mapvalue[x][y]);
s+=dfs(x,y+1,num,maxv);//也可以不取
}
return dp[x][y][num][maxv+1]=s%N;
}
int main(){
int i,j;
cin>>n>>m>>k;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
cin>>mapvalue[i][j];
}
memset(dp,-1,sizeof(dp));
dfs(1,1,0,-1);
cout<<dp[1][1][0][0];
return 0; }0.0分
16 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复