题目大意:给你一张n*n的图,每点位置输入一个值,给你一个k表示每次能够走的最大步数,然后走图路径的值为该情况的一条累和最大的递增序列,并输出这个最大值
解题思路:类似于三角形之和的动态规划的题目,由于是一张图,此时用记忆化搜索,出口是当你发现四个方向没有比自己本身再大的数,这里不用一个book保存该条搜索方向已走过的方向,也就是不怕他死循环,因为你走过的路径分别的值一定比你当前位置以及之后要走的来得小,一开始想写在终点保存最优值一直没写得出来(这点暂时还没想好怎么改,一直WA,注:可能状态定义也有点问题,因为从前面加到当前的最优值不一定是整体的最优值(这一点不一定对,可以忽略,参考算法竞赛入门经典训练指南 的三角形之和3得到的思路)),就用起点dp保存最优值,相当于dfs函数是找到(i,j)点之后的一条最优值路线的所有值的和
AC代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int map[110][110],k,n,aa[4][2]={0,1,1,0,0,-1,-1,0},dp[110][110];
bool pan(int x,int y)
{
if(x<0||x>n-1||y<0||y>n-1)
return false;
return true;
}
int dfs(int x,int y)
{
if(dp[x][y])
return dp[x][y];
int i,a,b,j,MAX=0,s;
for(i=0;i<4;i++)
{
for(j=1;j<=k;j++)
{
a=x+aa[i][0]*j;
b=y+aa[i][1]*j;
if(pan(a,b) && map[a][b]>map[x][y])
{
s=dfs(a,b);
if(MAX<s)
MAX=s;
}
}
}
dp[x][y]=MAX+map[x][y];
return dp[x][y];
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&k) && (n!=-1 || k!=-1))
{
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&map[i][j]);
dfs(0,0);
printf("%d\n",dp[0][0]);
}
return 0;
}