第一次,只用了普通的深搜,超时。然后去看了别人的代码,发现可以用记忆搜索。
用二维数组ans保存从某点出发可以积累到的food的最大数量,用深搜从起点开始处理。一个点的ans值一旦算出,之后就可以直接使用,不用再计算。
#include <iostream> using namespace std; const int MAP_SIZE = 105; int n,k; int map[MAP_SIZE][MAP_SIZE],ans[MAP_SIZE][MAP_SIZE]; int direction_x[5] = { 0,-1,1,0,0 };/* 上下左右 */ int direction_y[5] = { 0,0,0,-1,1 };/* 上下左右 */ int DFS(int x,int y) { int xx,yy; int max = 0; for (int i = 1;i <= 4;i ++)/* 找四个方向 */ { for (int j = 1;j <= k;j ++)/* 每次之多跑k步 */ { xx = x + direction_x[i] * j; yy = y + direction_y[i] * j; if (xx < 1 || xx > n || yy < 1 || yy > n)/* 坐标要合法 */ continue; if (map[x][y] >= map[xx][yy])/* 下一个点的食物要比上一个点多 */ continue; int temp; if (ans[xx][yy] == -1)/* 如果(xx,yy)点没有计算过,则先计算 */ temp = DFS(xx,yy); else temp = ans[xx][yy];/* ans[xx][yy]之前计算过,现在可以直接使用 */ max = max > temp ? max : temp; } } ans[x][y] = max + map[x][y]; return ans[x][y]; } int main () { while (scanf("%d%d",&n,&k) != -1) { if (n == -1 && k == -1) break; memset(ans,-1,sizeof(ans)); for (int i = 1;i <= n;i ++) for (int j = 1;j <= n;j ++) scanf("%d",&map[i][j]); printf("%d\n",DFS(1,1)); } return 0; }