HDU1078 FatMouse and Cheese (记忆化搜索+dp)

本文介绍了一种结合动态规划与搜索算法解决迷宫中老鼠寻找最多奶酪路径的问题。老鼠只能向下或向右跳跃前进,且每次获取的奶酪数量必须超过前一次。文章通过递归方式实现了记忆化搜索,避免重复计算。

题意:

有一只胖老鼠在一座N*N的迷宫里(它的位置原点,即点(0,0)),这座迷宫里每个点都分布着奶酪,每个点上有一个值,这个值表示改点所有的奶酪的数量。这只老鼠只可以往下或者向右走,而且每次可以跳跃K步(K步之内都可以),而且下一次吃得奶酪一定要比当前吃得奶酪要多,问你胖老鼠最多可以吃多少奶酪? 

原题:so each time he can run at most k locations to get into the hole before being caught by Top Killer. 这句让我看的很迷。


分析思路:那么因为他是可以在水平和垂直上面随便走的,所以这个DP就没有一定的方向性和子局面可以确定,所以只用DP是不好做出来的,这类采用DP+搜索的方法。

对于一个点(i,j),它有可能是由2*K种可能推得的,那么用DP做就不太好想,所以用记忆化搜索。定义dp[i][j]表示老鼠在第i行第j列这个位置可以吃到的最多奶酪数量,初始化为:dp[0][0]=cheese[0][0],接着记忆化搜索,每搜索到一个点,将它的后继结点的最大值算出来,并保存在数组中,如此循环。

dp[]i[j]表示的是FatMouse从dp[i][j]的地方开始走,他可以吃到的最多的东西。那么最后就是求dp[0][0]即可。


据我实验观察,该算法是先一直递归算出最后一个无法再往下递归的值,将其dp=map,让后再以其往前推,最终推出dp[0][0],

ac code

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
int n,k,mp[maxn][maxn],dp[maxn][maxn];
int t1[4]= {1,-1,0,0},t2[4]= {0,0,1,-1};
int DFS(int x,int y) {
	if(dp[x][y]!=0) return dp[x][y];//
	int xx,yy,ans=0;
	for(int i=0; i<4; i++) {
		for(int j=1; j<=k; j++) {
			xx=x+t1[i]*j;
			yy=y+t2[i]*j;
			if(xx>=0&&xx<n&&yy>=0&&yy<n&&mp[xx][yy]>mp[x][y]) { //先判断是否越界,后..
				ans=max(ans,DFS(xx,yy));
			}
		}
	}
	dp[x][y]=ans+mp[x][y];
	return dp[x][y];
}
int main() {
	while(cin>>n>>k) {
		if(n==-1&&k==-1) break;
		memset(dp,0,sizeof(dp));
		for(int i=0; i<n; i++)
			for(int j=0; j<n; j++)
				cin>>mp[i][j];
		cout<<DFS(0,0)<<endl;				
	}
	return 0;
}


1、数组开大了。

2、判断条件yy写成了y。md把所有能改的都改了一遍 觉得最没问题的判断条件居然出错了,其实检查过但太长就只看了x和后面的,也就是检查了开头和结尾,中间的yy放了过去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值