标签:des style blog http io ar color os sp
3 1 1 2 5 10 11 6 12 12 7 -1 -1
37
题意:老鼠初始时在nXn的矩阵的(0.0),每次最多向一个方向移动k格,每次移动过去的那个格子里面的数值必须比当前所在格子里面的大,求出路径上所有数值总和最大值
解析:
记忆化搜索,根据题意只好扩散性搜索,就是那种在一个点对于它能走到的所有点暴力搜索,这样会超时。
记忆化搜索是这样实现的:可以理解为结果的形成是反向的,从终点向起点(0,0)慢慢形成,每次搜索一个点周围能够满足条件的点,每找到一个点就继续递归找这个点周围满足条件的点,最终找到的点将会是数值最大的,也就是终点,这时把矩阵map中的数值记录起来当作所有用它当作终点的路径反向搜索的最大值,然后向上层返回这个值,而对于上一层的这个点来说,下面返回的就是下面那段路程的数值的最大值,于是将这个返回上来的值和这个点的数值加起来当作最大值。
我知道光说是不怎么会懂的,所以画了个图,方便大伙观摩,也为了以后复习的时候好看看,算做个笔记了。。
WA了一次,原因是写代码时听歌去了,没有考虑k
TLE了一次,原因是直接扩散性暴力搜索
#include <iostream>
#include <cstdio>
#include <cstring>
#define MM(a,b) a<b?b:a
using namespace std;
int n,m,map[111][111],sum[111][111],dd[4][2]={0,1,0,-1,1,0,-1,0};
int dfs(int X,int Y)
{
int i,j,k,l=0,x,y;
if(sum[X][Y])return sum[X][Y];
for(i=0;i<4;i++)//遍历四个方向
{
for(j=1;j<=m;j++)//遍历各个距离1-k
{
x=X+dd[i][0]*j;//取点
y=Y+dd[i][1]*j;
if(x>=0&&y>=0&&x<n&&y<n)//判断越界
{
if(map[x][y]>map[X][Y])//下一个点必须比当前点的数值大
{
k=dfs(x,y);//k记录下一个节点(x,y)的最大值
l=MM(l,k);//挑选最大
}
}
}
}
sum[X][Y]=l+map[X][Y];//可以走各个点的最大值中最大的那个+当前点的数值=当前点的最大值
return sum[X][Y];//返回当前点的最大值
}
int main (void)
{
int i,j,k,l;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==-1&&m==-1)break;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&map[i][j]);
}
}
memset(sum,0,sizeof(sum));
l=dfs(0,0);
printf("%d\n",l);
}
return 0;
}
感觉记忆化搜索是对搜索过程中的某些状态进行存储来去除重复搜索的耗时
HDU--1078--FatMouse and Cheese--记忆化搜索
标签:des style blog http io ar color os sp
原文地址:http://blog.csdn.net/jingdianitnan/article/details/41546005