CSES Solutions Grid Paths (DP) (original) (raw)
Last Updated : 23 Jul, 2025
Consider an **N X N grid whose squares may have traps. It is not allowed to move to a square with a trap. Your task is to calculate the number of paths from the upper-left square to the lower-right square. You can only move right or down.
**Note: '.' denotes an empty cell, and '*' denotes a trap.

Grid Paths
**Examples:
**Input: N = 4, grid[][] = {"....", ".*..", "...*", "*..."}
**Output: 3
**Explanation: There are 3 ways to reach the lower-right square, starting from the upper-left square.**Input: N = 3, grid[][] = {"...", "...", "..*"}
**Output: 0
**Explanation: There is no way to reach the lower-right square, starting from the upper-left square.
**Approach: To solve the problem, follow the below idea:
The problem can be solved using Dynamic Programming. Maintain a dp[][] table such that dp[r][c] = number of ways to reach row r, column c from cell(0, 0).
We say there is one way to reach (0,0), dp[0][0] = 1.
When navigating the grid where each cell contains either a '
.'or a '#', we can move either right or down. The number of ways to reach a particular cell is the sum of the ways to reach the cell above it and the ways to reach the cell to its left. Additionally, any cell containing a '#'is inaccessible (with zero ways to reach it). So, for each each cell (i, j), **dp[i][j] = dp[i - 1][j] + dp[i][j - 1].
**Step-by-step algorithm:
- Maintain a dp[][] array such that dp[i][j] stores the number of ways to reach cell(i, j) from cell(0, 0).
- Initialize all the cells of dp[][] array with 0.
- Fill the first row with 1s starting from (0, 0) till we encounter a blocked cell.
- Fill the first column with 1s starting from (0, 0) till we encounter a blocked cell.
- For all the other cells (i, j):
- If the cell is blocked, dp[i][j] = 0.
- If the cell is empty, dp[i][j] = dp[i - 1][j] + dp[i][j - 1].
- After all the iterations, return dp[N-1][N-1] as the final answer.
Below is the implementation of the algorithm:
C++ `
#include <bits/stdc++.h> #define ll long long int #define mod 1000000007 using namespace std;
ll solve(vector& grid, ll N) { // dp[][] array such that dp[i][j] stores the number of // ways to reach cell(i, j) from cell(0, 0) vector<vector > dp(N, vector(N, 0));
// Finding the number of ways for the first column
for (int i = 0; i < N; i++) {
if (grid[i][0] == '*')
break;
dp[i][0] = 1;
}
// Finding the number of ways for the first row
for (int j = 0; j < N; j++) {
if (grid[0][j] == '*')
break;
dp[0][j] = 1;
}
// Finding the number of ways for the remaining grid
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
// If the cell is blocked, then move to the next
// cell
if (grid[i][j] == '*')
continue;
// The number of ways to reach cell(i, j) =
// number of ways to reach cell (i-1,j) + number
// of ways to reach cell(i,j-1)
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
}
}
// Return the number of ways to reach the last cell of the grid
return dp[N - 1][N -1];}
int main() { // Sample Input ll N = 4; vector grid = {"....", "...", "...", "*..."};
cout << solve(grid, N) << "\n";}
Java
import java.util.*;
public class Main {
// Function to find the number of ways to the reach the bottom-right cell
static long GFG(ArrayList grid, int N, int mod) {
long[][] dp = new long[N][N];
// Finding the number of ways for first column
for (int i = 0; i < N; i++) {
if (grid.get(i).charAt(0) == '')
break;
dp[i][0] = 1;
}
// Finding the number of ways for the first row
for (int j = 0; j < N; j++) {
if (grid.get(0).charAt(j) == '*')
break;
dp[0][j] = 1;
}
// Finding the number of ways for remaining grid
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
// If the cell is blocked, then move to the next cell
if (grid.get(i).charAt(j) == '*')
continue;
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
}
}
return dp[N - 1][N - 1];
}
public static void main(String[] args) {
// Input
int N = 4;
ArrayList grid = new ArrayList<>(Arrays.asList("....", "...", "...", "..."));
int mod = 1000000007;
System.out.println(GFG(grid, N, mod));
}
}
C#
using System; using System.Collections.Generic;
public class Geeks { // Function to find the number of ways to reach the bottom-right cell static long GFG(List grid, int N, int mod) { long[,] dp = new long[N, N]; // Finding the number of ways for first column for (int i = 0; i < N; i++) { if (grid[i][0] == '') break; dp[i, 0] = 1; } // Finding the number of ways for the first row for (int j = 0; j < N; j++) { if (grid[0][j] == '*') break; dp[0, j] = 1; } // Finding the number of ways for remaining grid for (int i = 1; i < N; i++) { for (int j = 1; j < N; j++) { // If the cell is blocked, then move to the next cell if (grid[i][j] == '*') continue; dp[i, j] = (dp[i - 1, j] + dp[i, j - 1]) % mod; } } return dp[N - 1, N - 1]; } public static void Main(string[] args) { // Input int N = 4; List grid = new List { "....", "...", "...", "..." }; int mod = 1000000007; Console.WriteLine(GFG(grid, N, mod)); } }
JavaScript
function GFG(grid, N) { const mod = 1000000007; // Initialize dp array to store the number of the ways to reach each cell const dp = Array.from({ length: N }, () => Array(N).fill(0)); for (let i = 0; i < N; i++) { if (grid[i][0] === '') break; dp[i][0] = 1; } // Finding the number of ways for the first row for (let j = 0; j < N; j++) { if (grid[0][j] === '') break; dp[0][j] = 1; } // Finding the number of ways for remaining grid for (let i = 1; i < N; i++) { for (let j = 1; j < N; j++) { // If the cell is blocked, then move to the next cell if (grid[i][j] === '') continue; dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod; } } return dp[N - 1][N - 1]; } // Sample Input const N = 4; const grid = ["....", "...", "...", "..."]; console.log(GFG(grid, N));
Python3
def GFG(grid, N): mod = 1000000007 # Initialize dp array to store the number of the ways to reach each cell dp = [[0]N for _ in range(N)] for i in range(N): if grid[i][0] == '': break dp[i][0] = 1 # Finding the number of ways for the first row for j in range(N): if grid[0][j] == '': break dp[0][j] = 1 # Finding the number of ways for remaining grid for i in range(1, N): for j in range(1, N): # If the cell is blocked, then move to the next cell if grid[i][j] == '': continue dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod return dp[N - 1][N - 1]
Sample Input
N = 4 grid = ["....", "...", "...", "*..."] print(GFG(grid, N))
`
**Time Complexity: O(N * N), where **N is the number of rows or columns in the grid.
**Auxiliary Space: O(N * N)