题意:老鼠每次最多走k步停下来,停下的这个位置只能比上一个停留的位置大,并获取其价值,每次只能水平或垂直走,问最大能得到的价值解题思路:这道题可以用记忆化搜索解决,dp[i][j]表示老鼠在位置(i,j)时可以达到的最优值。因为dp的状态是一个有向无环图,刚开始想会不会走死循环,但是这道题有一个条件:下一个位置比当前位置的值要大,所以说既然能到当前位置,那么之前的位置是不可能再次走到的。记忆化搜索实际上感觉就是在一颗解答树上进行剪枝,应该算是一种搜索的策略。#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100; int n,k,mat[maxn][maxn],dp[maxn][maxn]; int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; bool check(int x,int y,int newx,int newy) { if(newx < 0 || newx >= n || newy < 0 || newy >= n) return false; if(mat[x][y] >= mat[newx][newy]) return false; return true; } void dfsDP(int x,int y) { if(dp[x][y] != -1) return; for(int i = 0; i < 4; i++) //方向 for(int j = 1; j <= k; j++) //步数 { int newx = x + j * dir[i][0]; int newy = y + j * dir[i][1]; if(check(x,y,newx,newy) == false) continue; dfsDP(newx,newy); dp[x][y] = max(dp[x][y],mat[x][y] + dp[newx][newy]); } if(dp[x][y] == -1) dp[x][y] = mat[x][y]; } int main() { while(scanf("%d%d",&n,&k)!=EOF) { if(n == -1 && k == -1) break; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) scanf("%d",&mat[i][j]); memset(dp,-1,sizeof(dp)); dfsDP(0,0); printf("%d\n",dp[0][0]); } return 0; }
hdu 1078(记忆化搜索)
最新推荐文章于 2018-08-21 11:50:54 发布