HDOJ 1078 记忆搜索

第一次,只用了普通的深搜,超时。然后去看了别人的代码,发现可以用记忆搜索。

用二维数组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;
}
posted @ 2012-08-11 19:34  peaceful  阅读(178)  评论(0)    收藏  举报