蓝桥杯2014年第五届真题-地宫取宝(DFS+动态规划)

1.题目描述在这里插入图片描述

2.输入输出样例在这里插入图片描述

3.解题思路

很明显,这是一个dfs进行暴力搜索的题,但只使用DFS很容易超时,所以要进行剪枝,即为记忆化搜索。同时,定义状态dp[x][y][num][maxv]。这代表第x行第y列,此时的获得了num个宝物,宝物中的最大价值为maxv。状态为1表示一种方案,状态为0表示不是一种方案。

4.源代码

#include<bits/stdc++.h>
#define N 1000000007 
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)); //注意将dp数组初始化为-1,因为宝物价值有可能是0 
    dfs(1,1,0,-1);
    cout<<dp[1][1][0][0];
return 0; }

5.总结

注意不能直接进行FS,否则会超时,要进行记忆化。同时,动态规划这一块,没怎么学过,要加强

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chase__young

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值