http://acm.hdu.edu.cn/showproblem.php?pid=1535
题意:老鼠在一个图内藏了许多奶酪,输入图中每个方格中有若干奶酪。老鼠一次可以移动k个单位(每个方格一个单位),然后吃掉该方格的所有奶酪。但是每吃掉奶酪后这个老鼠就会变胖而失去行动力,要想继续移动(必须移动,因为后面有猫追着),必须移动到下一个更多奶酪的地方补充能量,完毕后才能继续移动。老鼠不能越界。问老鼠在这个图中最多可以吃到多少奶酪。
ps:记忆化搜索第一道。
思路:记忆化搜索有个共性,以某点为起点的目标值是固定的,这样可以大大减少搜索量。搜索最低端的值是最小值,到起点越来越大。这样找出来的结果就是起点所能获得的最大值(适用于任何变量)。注意累加的条件不要漏掉。
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 105;
const int INF = 0x3f3f3f3f;
int k, n, G[N][N], dp[N][N];
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
bool check(int x, int y)
{
if(x>=1 && x<=n && y>=1 && y<=n) return true;
else return false;
}
int dfs(int x, int y)
{
if(dp[x][y] > 0) return dp[x][y];
else
{
int Max = 0;//Max代表以本次递归(x,y)为起点当前所遍历到的所有路线的最大获取量
for(int i = 1; i <= k; i++)
{
for(int j = 0; j < 4; j++)
{
int sum = 0;//sum代表本次递归所寻到的以(xx,yy)为起点所有路线的最大获取量
int xx = x+dir[j][0]*i;
int yy = y+dir[j][1]*i;
if(check(xx, yy) && (G[xx][yy]>G[x][y]))//如果找到新节点
{
// printf("asd1");
sum+=dfs(xx, yy);
Max = max(Max, sum);
}
}
}
dp[x][y] = Max+G[x][y];
return dp[x][y];
}
}
int main()
{
// freopen("in.txt", "r", stdin);
while(~scanf("%d%d", &n, &k))
{
if(n==-1 && k==-1) break;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &G[i][j]);
memset(dp, 0, sizeof(dp));
printf("%d\n", dfs(1, 1));
}
return 0;
}