胖老鼠和奶酪(记忆化dfs)

问题描述
FatMouse在一个城市中存储了一些奶酪。可以将城市视为尺寸为n的正方形网格:每个网格位置都标记为(p,q),其中0 <= p

FatMouse首先站在位置(0,0)。他吃掉了他站立的奶酪,然后水平或垂直跑到另一个位置。问题在于,有一只名为Top Killer的超级猫坐在他的洞附近,因此每次他最多可以跑k个位置进入洞中,然后再被Top Killer抓住。更糟糕的是-在一个地方吃完奶酪后,FatMouse变得更胖。因此,为了获得足够的能量进行下一次跑步,他必须跑到一个位置,那里的奶酪块比当前洞中的奶酪块多。

给定n,k和每个网格位置处的奶酪块数,请计算FatMouse在无法移动之前可以食用的最大奶酪量。

输入值
有几个测试用例。每个测试用例由一行包含两个介于1和100之间的整数的行组成:n和kn行,每个行都有n个数字:第一行包含位置(0,0)(0,1)处的奶酪块数。 (0,n-1); 下一行包含在(1,0),(1,1),…(1,n-1)等位置的奶酪块数。输入以一对-1结尾。

输出量
对于一行中的每个测试用例输出,单个整数给出收集的奶酪块数。

样本输入
3 1
1 2 5
10 11 6
12 12 7
-1 -1

样本输出
37

资源
浙江大学训练比赛2001

  • 需要通过记忆化保存每个点的最优解
  • 下次递归就可以直接调用
#include
using namespace std;
int n, k;
int a[1000][1000];
int dp[1000][1000];
int dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
int dfs(int x, int y){
	int ans = 0;
	if(dp[x][y]) return dp[x][y];
	
	for(int i = 0; i < 4; i ++){
		for(int j = 1; j <= k; j ++){
			int tx = x + dir[i][0] * j;
			int ty = y + dir[i][1] * j;
			if(tx < 0 || ty < 0 || tx > n - 1 || ty > n - 1)continue;
			if(a[tx][ty] < a[x][y])continue;
			ans = max(ans,dfs(tx, ty));
		}
	}
	dp[x][y] = ans + a[x][y];
	return dp[x][y];
}
int main(){
	ios::sync_with_stdio(false);
    while(cin >> n >> k){
    	if(n == -1 && k == -1)break;
    	memset(dp,0,sizeof(dp));
    	for(int i = 0; i < n; i ++)
    		for(int j = 0; j < n; j ++)
    		cin >> a[i][j];
    	
    	dfs(0,0);
    	cout << dp[0][0] << endl;
	}
} 



你可能感兴趣的:(胖老鼠和奶酪(记忆化dfs))