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

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:

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)