hdu 1428校园漫步(记忆化搜索)

题目需要好好读懂......(不看题解就卡住了)

先求出各个点到(n, n)的最短距离(通过这个题还掌握了bfs求全局各个点到某一终点的距离 ,巧妙)。

然后搜索 + 记忆化。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 60;
const int inf = 1e9;
int dis[maxn][maxn];
int sum[maxn][maxn];
int dir[4][2] = {{-1, 0}, {0, -1}, {0, 1}, {1,0}};
int n;

struct Node
{
    int x, y;
    Node(int xx, int yy)
    {
        x = xx; y = yy;
    }
};
bool vis[maxn][maxn];
ll dp[maxn][maxn];

bool judge(int x, int y)
{
    if(x < 1 || x > n || y < 1 || y > n)    return false;
    return true;
}

void bfs()                          //巧妙! 求每个点到(n, n)的最短路
{
    queue<Node> q;

    sum[n][n] = dis[n][n];
    vis[n][n] = 1;
    q.push(Node(n, n));
    while(!q.empty())
    {
        Node top = q.front();   q.pop();
        int curx = top.x, cury = top.y;
        vis[curx][cury] = 0;                        //can ignore
        //cout << curx << " " << cury << ": " << sum[curx][cury] << endl;
        for(int i = 0; i < 4; i++)
        {
            int nx = curx + dir[i][0];
            int ny = cury + dir[i][1];
            if(judge(nx, ny))
            {
                if(sum[nx][ny] > sum[curx][cury] + dis[nx][ny])
                {
                    sum[nx][ny] = sum[curx][cury] + dis[nx][ny];
                    if(!vis[nx][ny])                                        //
                    {
                        //cout << "push " << nx << " " << nx << endl;
                        q.push(Node(nx, ny));
                        vis[nx][ny] = 1;
                    }
                }
            }
        }
    }
}



ll dfs(int x, int y)
{
    //if(x < 1 || x > n || y < 1 || y > n)    return 0;

    if(dp[x][y] != -1)
        return dp[x][y];

    if(x == n && y == n)
        return 1;

    int ret = 0;
    for(int i = 0; i < 4; i++)
    {
        //int num = 0;
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if(judge(nx, ny) && sum[nx][ny] < sum[x][y])
        {
            ret += dfs(nx, ny);
        }
    }
    return dp[x][y] = ret;
}


int main()
{
    while(scanf("%d", &n) == 1)
    {

        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                cin >> dis[i][j];
                sum[i][j] = inf;
            }
        }

        bfs();
        memset(vis, 0, sizeof(vis));
        memset(dp, -1, sizeof(dp));
        ll ans = dfs(1, 1);
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38577732/article/details/89307383
今日推荐