要求:n*n的方格,每个格子有一个数字,要求从(0,0)开始移动,每次最多移动k格,移动的条件是下一个位置的数字比当前的位置的数字大,求移动到不能移动的位置时经过的格子的数字和最大值。
方法:记忆化搜索
1.记忆化搜索就是备忘录方法。
2.dp[x][y]表示从位置(x,y)出发的经过的格子的数字和最大值。
3.每次移动k格可用for循环写,从当前位置向四个方向分别移动1 - k格,包括了所有情况。假设从(0,0)开始,k=5 ,要移动到(2,3),则需要一个折线,包含于两小段2 和 3内。故只要从当前位置向四个方向分别移动1 - k格即可。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
int n,k;
int map1[105][105];
int dp[105][105];
int row[4]={0,0,-1,1};
int col[4]={-1,1,0,0};
int dfs(int x,int y)
{
int i,j;
int xx,yy;
if(dp[x][y] > 0)
return dp[x][y];
dp[x][y] = map1[x][y] ;
for(i = 1 ; i <= k ; i ++)//暴力移动1-k格的所有可能
{
for(j = 0 ; j < 4 ; j ++)
{
xx = x + row[j] * i ;
yy = y + col[j] * i ;
if(xx < 0 || xx >= n || yy < 0 || yy >= n)
continue;
if(map1[xx][yy] > map1[x][y])
{
dp[x][y] = max(dp[x][y],map1[x][y]+dfs(xx,yy)) ;
}
}
}
return dp[x][y] ;
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&k)&&!(n==-1&&k==-1))
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&map1[i][j]);
memset(dp,0,sizeof(dp));
dp[0][0]=dfs(0,0);
printf("%d\n",dp[0][0]);
}
}