HDU 1078 記憶化搜尋
阿新 • • 發佈:2019-01-07
要求: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]); } }