题意:
有一只胖老鼠在一座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放了过去