2011-2012 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2011)Problem A Robots on a grid(迷宫dp)

题目链接:http://codeforces.com/gym/101555/attachments

题意:现在有一个迷宫,迷宫的图给出,首先你需要从左上角走到右下角,每次只能向下走或者向右走,问有几种走法。如果不能走到,那就四个方向随意走,问能不能从左上走到右下。

解题心得:

  1. 当时看见这个简单题队友就直接上了,结果敲了好一会儿敲不出来,然后看得我心急,我就自己上去敲,但是就是跑不出样例,结果发现是队友输入写错了,蜜汁尴尬的一个BUG。
  2. 其实做法很简单,刚开始在计算走法的时候就是一个最简单的dp,先将第一行和第一列在不遇到’#'的时候初始化为1,主要注意一下初始化和在迷宫中是否可以转移的问题。转移方程式:dp[i][j] = dp[i-1][j] + dp[i][j-1]。最后检验dp[n][n]是否不可达,如果不可达那就从左上点开始跑一个BFS就解决问题了。
#include 

using namespace std;
const int maxn = 1005;
typedef long long ll;
const ll mod = INT_MAX;
char mp[maxn][maxn];
ll dp[maxn][maxn];
int n, dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};

bool vis[maxn][maxn];

bool checke(int x,int y) {//检验点(x, y)是否符合条件
    if(x <= 0 || y <= 0 || x >n || y> n || vis[x][y] || mp[x][y] == '#')
        return false;
    return true;
}

void DP() {//先检验第一种走法
    for (int i = 1; i <= n; i++) {
        if(mp[1][i] == '.') dp[1][i] = 1;
        else break;
    }

    for(int i=1;i<=n;i++) {
        if(mp[i][1] == '.') dp[i][1] = 1;
        else break;
    }

    for(int i=2;i<=n;i++){
        for(int j=2;j<=n;j++){
            if(mp[i][j] =='#') continue;
            if(dp[i-1][j] + dp[i][j-1] == -2) continue;//该点无法转移到达
            dp[i][j] = (max(dp[i-1][j], 0ll) + max(0ll, dp[i][j-1])) % mod;
        }
    }
}

bool BFS() {//第一种走法无法达到那么走bfs
    queue <pair<int,int> > qu;

    qu.push(make_pair(1,1));
    vis[1][1] = true;
    while(!qu.empty()) {
        pair <int, int> now = qu.front(); qu.pop();
        for(int i=0;i<4;i++) {
            int nx = now.first + dir[i][0];
            int ny = now.second + dir[i][1];

            if(checke(nx, ny)) {
                qu.push(make_pair(nx, ny));
                vis[nx][ny] = true;
                if(nx == n && ny == n) return true;
            }
        }
    }
    return false;
}

int main() {
//    freopen("1.in","r",stdin);
    scanf("%d", &n);
    memset(dp, -1, sizeof dp);
    for (int i = 1; i <= n; i++) scanf("%s", mp[i]+1);

    DP();
    
    if(dp[n][n] == -1) {
        if(BFS()) {
            printf("THE GAME IS A LIE\n");
        } else {
            printf("INCONCEIVABLE\n");
        }
    } else {
        cout << dp[n][n] << endl;
    }
    return 0;
}

你可能感兴趣的:(搜索-BFS,动态规划-简单DP,dp,宽度优先搜索)