1. 程式人生 > >HDU 1078 記憶化搜尋

HDU 1078 記憶化搜尋

要求: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]);
  }
}