JavaScript Solution - Top Down with Memoization & 2 DP Approaches
Top Down Approach with Memoization #####\n\n\n\nvar knightProbability = function(N, K, r, c) {\n    const dirs = [[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1
##### Top Down Approach with Memoization #####\n<br>\n\n```\nvar knightProbability = function(N, K, r, c) {\n    const dirs = [[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1, -2], [-1, 2], [-1, -2]];\n    const memo = new Map();\n    \n    return findProbs(K, r, c);\n    \n    function findProbs(k, r, c) {\n        const key = `${k}#${r}#${c}`;\n        \n        // base case\n        if (isOutOfBound(r, c)) return 0.0; // .0 is for completeness sake. Don\'t really need it in JavaScript\n        if (k === 0) return 1.0;\n        if (memo.has(key)) return memo.get(key);\n        \n        let prob = 0;\n        \n        for (const [dirX, dirY] of dirs) {\n            prob += 0.125 * findProbs(k - 1, r + dirX, c + dirY);\n        }\n        \n        memo.set(key, prob);\n        \n        return prob;\n        \n    }\n    \n    function isOutOfBound(row, col) {\n        return row < 0 || col < 0 || row >= N || col >= N;\n    }\n};\n```\n<br>\n\n----\n\n<br>\n\n##### DP Approach  with O(N^2 * K) Space Complexity #####\n\n<br>\n\n```\nvar knightProbability = function(N, K, r, c) {\n    const dirs = [[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1, -2], [-1, 2], [-1, -2]];\n    const probs = constructProbs(K);\n    \n    probs[0][r][c] = 1.0;\n    \n    for (let k = 1; k <= K; k++) {\n        for (let i = 0; i < N; i++) {\n            for (let j = 0; j < N; j++) {\n                for (const [dirX, dirY] of dirs) {\n                    const currRank = i + dirX;\n                    const currFile = j + dirY;\n                    \n                    if (withinBound(currRank, currFile)) {\n                        probs[k][currRank][currFile] += (probs[k - 1][i][j] * 0.125);\n                    }\n                }\n            }\n        }\n    }\n    \n    let ans = 0;\n    \n    for (let i = 0; i < N; i++) {\n        for (let j = 0; j < N; j++) {\n            ans += probs[K][i][j];\n        }\n    }\n    \n    return ans;\n    \n    function constructProbs(K) {\n        const probs = [];\n        \n        for (let k = 0; k <= K; k++) {\n            probs[k] = [];\n            \n            for (let i = 0; i < N; i++) {\n                probs[k][i] = new Array(N).fill(0);\n            }\n        }\n        \n        return probs;\n    }\n    \n    function withinBound(row, col) {\n        return row >= 0 && col >= 0 && row < N && col < N;\n    }\n};\n```\n<br>\n\n---\n\n<br>\n\n##### DP with O(N^2) Spacex Complexity #####\n\n<br>\n\n```\nvar knightProbability = function(N, K, r, c) {\n    const dirs = [[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1, -2], [-1, 2], [-1, -2]];\n    let prevProbs = constructProbs(K);\n    \n    prevProbs[r][c] = 1;\n    \n    for (let k = 1; k <= K; k++) {\n        const newProbs = constructProbs(K);\n              \n        for (let i = 0; i < N; i++) {\n            for (let j = 0; j < N; j++) {\n                for (const [dirX, dirY] of dirs) {\n                    const currRank = i + dirX;\n                    const currFile = j + dirY;\n                    \n                    if (withinBound(currRank, currFile)) {\n                        newProbs[currRank][currFile] += (prevProbs[i][j] / 8.0);\n                    }\n                }\n            }\n        }\n        \n        prevProbs = newProbs;\n    }\n    \n    let ans = 0;\n    \n    for (let i = 0; i < N; i++) {\n        for (let j = 0; j < N; j++) {\n            ans += prevProbs[i][j];\n        }\n    }\n    \n    return ans;\n    \n    function constructProbs(K) {\n        const dp = [];\n            \n        for (let i = 0; i < N; i++) {\n            dp[i] = new Array(N).fill(0);\n        }\n        \n        return dp;\n    }\n    \n    function withinBound(row, col) {\n        return row >= 0 && col >= 0 && row < N && col < N;\n    }\n};\n```
['Dynamic Programming', 'Memoization', 'JavaScript']