CSES Solutions – Grid Paths (DP)
Last Updated :
27 Mar, 2024
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] = 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<string>& 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<ll> > dp(N, vector<ll>(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<string> 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<String> 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<String> 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<string> 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<string> grid = new List<string> { "....", ".*..", "...*", "*..." };
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)
Share your thoughts in the comments
Please Login to comment...