zoukankan      html  css  js  c++  java
  • 漫步校园 杭电1428

    LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域。例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n)。因有多条路线可以选择,LL希望每次的散步路线都不一样。另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了…)。现在他想知道的是,所有满足要求的路线一共有多少条。你能告诉他吗? 

    Input每组测试数据的第一行为n(2=<n<=50),接下来的n行每行有n个数,代表经过每个区域所花的时间t(0<t<=50)(由于寝室与机房均在三楼,故起点与终点也得费时)。 
    Output针对每组测试数据,输出总的路线数(小于2^63)。 
    Sample Input

    3
    1 2 3
    1 2 3
    1 2 3
    3
    1 1 1
    1 1 1
    1 1 1

    Sample Output

    1
    6
    题目大意::就是从起点左上角的(1,1)到右下角的(n,n)最短路线一共有多少条!!
    思路::开一个数组step,用bfs求数组中每一点到终点的最短距离,然后用DFS记忆化搜索,条件就是在step数组中从起点到终点的每一步都是要递减的。
    AC代码:
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define INF 100000000
    using namespace std;
    typedef long long ll;
    struct stu{
        int a,b;
    };
    int n;
    ll arr[52][52];
    ll step[52][52];
    ll dp[52][52];
    int d[4][2]={1,0,0,1,0,-1,-1,0};
    void bfs(int x,int y){
        queue<stu>que;
        que.push({x,y});
        step[x][y]=arr[x][y];
        while(que.size()){
            int xx=que.front().a;
            int yy=que.front().b;
            que.pop();
            for(int i=0;i<4;i++){
                int dx=xx+d[i][0];
                int dy=yy+d[i][1];
                if(dx>=1&&dy>=1&&dx<=n&&dy<=n){
                    if(step[dx][dy]>step[xx][yy]+arr[dx][dy]){
                        step[dx][dy]=step[xx][yy]+arr[dx][dy];//更新step数组,使他保存较小的的距离 
                        que.push({dx,dy});
                    }
                }
            }
        } 
    }
    
    ll dfs(int x,int y){
        if(dp[x][y]) return dp[x][y];
        else {
            for(int i=0;i<4;i++)
            {
                int dx=x+d[i][0];
                int dy=y+d[i][1];
                if(dx>=1&&dy>=1&&dx<=n&&dy<=n)
                {
                    if(step[dx][dy]<step[x][y])
                        dp[x][y]+=dfs(dx,dy);//只有发生回溯的时候才会更新dp数组,并且会按照路径回溯,只有当(x,y)有多个方向满足条件时,才会发生叠加,即有对多条路径可以选择;
                }
            }
        }
        return dp[x][y];
    }
    
    int main(){
        while(cin>>n)
        {
            for(int i=0;i<=50;i++){
                for(int j=0;j<=50;j++)
                    step[i][j]=INF;
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    cin>>arr[i][j];
                }
            }
            bfs(n,n);
            memset(dp,0,sizeof(dp));
            dp[n][n]=1;//终点初始化为1,因为只有走到终点才会发生回溯。(即无路可走了就会发生回溯)
            cout<<dfs(1,1)<<endl;
        }
        return 0;
    }






  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/Accepting/p/11272635.html
Copyright © 2011-2022 走看看