688. Knight Probability in Chessboard

问题描述:

On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exactly K moves. The rows and columns are 0 indexed, so the top-left square is (0, 0), and the bottom-right square is (N-1, N-1).

A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.

 

 

Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there.

The knight continues moving until it has made exactly K moves or has moved off the chessboard. Return the probability that the knight remains on the board after it has stopped moving.

解题思路:

这道题一开始我觉得可以用BFS来解,但是有超时和空间溢出的风险,毕竟题目中没有限定不可以反复横跳(在两个地方瞎蹦跶,是一个可行的解:))

但是我没有想到更好的解法,然后就BFS了,然后就out of memory limit 了【手动再见】

 

一般这种情况当然是去看GrandYang的解法啦 (⁎⁍̴̛ᴗ⁍̴̛⁎)

居然使用DP解。。。

建立一个新的矩阵存储从起始点经过i步到达这个位置的概率。

遍历新的矩阵。

对某个位置看看它可以从哪里来,然后算一下它跳过来的概率。

更新矩阵K次。

最后把在矩阵上的概率求和,就是最后我们需要的解了。

 

时间复杂度:O(KN^2)

空间复杂度:O(N^2)

 

 

代码:

class Solution {
public:
    double knightProbability(int N, int K, int r, int c) {
        if(K == 0) return 1.0;
        int dr[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
        int dc[8] = {1, 2, 2, 1, -1, -2, -2, -1};
        
        vector<vector<double> > dp(N, vector<double>(N, 0.0));
        dp[r][c] = 1.0;
        for(; K > 0; K--){
            vector<vector<double> > tmpDP(N, vector<double>(N, 0.0));
            for(int i = 0; i < N; ++i){
                for(int j = 0; j < N; ++j){
                    for(int k = 0; k < 8; ++k){
                        int cr = i + dr[k];
                        int cc = j + dc[k];
                        if(cr < 0 || cr >= N || cc < 0 || cc >= N){
                            continue;
                        }
                        tmpDP[cr][cc] += dp[i][j] / 8.0;
                    }
                }
            }
            dp = tmpDP;
        }
        double ans = 0;
        for(auto r : dp){
            for(auto  v : r){
                ans += v;
            }
        }
        return ans;
    }
};

 

posted @ 2019-10-21 03:04  妖域大都督  阅读(162)  评论(0编辑  收藏  举报