zoj 1107 FatMouse and Cheese 逆向动态规划

                                                                                      FatMouse and Cheese

 

开始试着用深度搜索做,超时了(对于时间复杂度没有概念)

这道题用动态规划。如果用自顶向下的方法,我们不知道结尾的是哪个点,所以不方便用。

如果我们采用自下而上的方法,用eatNum[i][j]表示从起点到达i, j 位置老鼠所吃的奶酪数,问题是一个节点可由几中不同的路径不同时得到,所以也会发现也会有重复的路要走。

书上的动态规划方法其实挺妙。用起点作为终点的样子,自顶向下,把结果集结到起点。看来我的思维是太局限了。

向各个方向探索用一个for循环实现也是非常值得借鉴的。

#include <iostream>
#include <cstring>
using namespace std;
#define size 110

int a[size][size], n, k, eatNum[size][size];

int memSearch(int r, int c){
	int r1, c1;		//新的位置
	int Max = 0;
	int i, temp;

	if(eatNum[r][c] != -1)	//中间结果
		return eatNum[r][c];

	//每次让FatMouse走一步,直到走k步
	for(i = 1; i <= k; i++){
		//上
		r1 = r - i;
		if(r1 >= 1 && r1 <= n && a[r1][c] > a[r][c]){
			temp = memSearch(r1, c);
			if(temp > Max)
				Max = temp;
		}
		//下
		r1 = r + i;
		if(r1 >= 1 && r1 <= n && a[r1][c] > a[r][c]){
			temp = memSearch(r1, c);
			if(temp > Max)
				Max = temp;
		}
		
		//左
		c1 = c - i;
		if(c1 >= 1 && c1 <= n && a[r][c1] > a[r][c]){
			temp = memSearch(r, c1);
			if(temp > Max)
				Max = temp;
		}
		
		//右
		c1 = c + i;
		if(c1 >= 1 && c1 <= n && a[r][c1] > a[r][c]){
			temp = memSearch(r, c1);
			if(temp > Max)
				Max = temp;
		}
	}
	eatNum[r][c] = Max + a[r][c];
	return eatNum[r][c];
}

int main(){
	//freopen("in.txt", "r", stdin);
	int i, j;
	while(cin>>n>>k){
		if(n == -1 && k == -1)
			break;
		memset(eatNum, -1, sizeof(eatNum));	//存储中间结果
		for(i = 1; i <= n; i++){
			for(j = 1; j <= n; j++)
				cin>>a[i][j];				//接收数据
		}
		cout<<memSearch(1, 1)<<endl;
	}
	return 0;
}


 

 

 

你可能感兴趣的:(动态规划,ACM)