题目链接:
点击打开链接
肥老鼠从(0,0)出发,每次最多水平或垂直移动K步(连续向同一方向),且移动停下的位置的cheese必须大于之前的,否则就被猫吃掉,求老鼠最多吃多少奶酪。
刚接触dp尝试分析一下,方便自己理解
dp[x][y]表示在从x,y出发移动k步最多可以吃到的奶酪数量 dp[x][y] = max(dp[nx][ny]+map[x][y],dp[x][y]);
dp[nx][ny] 对应 dfs(nx,ny) dp[x][y]开始为map[x][y] 如果 之后的值大于 map[x][y]则其会被更新,所以为了更新,用临时res代替map[x][y]
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAX 105
using namespace std;
int dp[MAX][MAX];
int n,k;
int map[MAX][MAX];
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int dfs(int x, int y)
{
if(dp[x][y] != -1)
return dp[x][y];
int res = map[x][y];//dp[x][y]最少为map[x][y] 终点时候 就是此值
for(int i = 0; i < 4; ++i){
for(int j = 1; j <= k; ++j){
int nx = x + j*dir[i][0];
int ny = y + j*dir[i][1];
if(nx>=0 && nx<n && ny>=0 &&ny<n && map[nx][ny] > map[x][y]){
res = max(res,dfs(nx,ny)+map[x][y]);//就是状态转移方程的 搜索形式
}
}
}
return dp[x][y] = res;
}
int main()
{
std::ios::sync_with_stdio(false);//加快读取速度
while(cin >> n >> k){
if(n == -1 && k == -1)
break;
memset(dp,-1,sizeof(dp));
memset(map,0,sizeof(map));
for(int i = 0; i < n; ++i){
for(int j = 0; j < n; ++j){
cin >> map[i][j];
}
}
int ans = dfs(0,0);
cout << ans <<endl;
}
return 0;
}