hdu1428 漫步校园

hdu1428 漫步校园

思路:有几条可到达的路线是很常规的dp,假设u->v ,那么dp[u]+=dp[v]

下一步一定要更加逼近终点而不是远离终点,用bfs去跑距(n,n)的最短路径。

本题可以与dijkstra堆优化过程中统计最短路条数进行对比:

本题:dp[i][j] (i,j)到终点的最短路条数;采用记忆化搜索方式,自下而上

dijkstra堆优化:dp[i] 代表起点到i的最短路条数;递推,自上而下

 

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=55;
typedef long long LL;
struct node
{
    int x,y;
    LL s;
    node(){}
    node(int x,int y,LL s):x(x),y(y),s(s){}
    bool operator<(const node &rhs)const
    {
        return s>rhs.s;
    }
};

int a[N][N];
int vis[N][N];
int dist[N][N];
LL dp[N][N];           //从i,j出发到终点有多少条路
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n;
void bfs()
{
    priority_queue<node> q;
    memset(dist,0,sizeof(dist));
    q.push(node(n,n,1));
    dist[n][n]=1;
    while(!q.empty())
    {
        node p=q.top();
        q.pop();
        int x=p.x, y=p.y;
        LL s=p.s;
        for(int i=0;i<4;++i)
        {
            int nx=x+dx[i],ny=y+dy[i];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&!dist[nx][ny])
            {
                dist[nx][ny]=s+a[nx][ny];
                q.push(node(nx,ny,dist[nx][ny]));
            }
        }
    }
}

LL dfs(int x,int y)
{
    if(vis[x][y]) return dp[x][y];
    vis[x][y]=1;
    for(int i=0;i<4;++i)
        {
            int nx=x+dx[i],ny=y+dy[i];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&dist[nx][ny]<dist[x][y])
            {
                dp[x][y]+=dfs(nx,ny);
            }
        }
    return dp[x][y];

}
int main()
{
    while(cin>>n)
    {
        memset(vis,0,sizeof(vis));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                cin>>a[i][j];
            }
        bfs();
        dp[n][n]=1;
        cout<<dfs(1,1)<<endl;
    }


}