Open In App

Count the number of ways a person can walk, roll or jump

A person has to cover a distance, He can either walk, roll, or jump, each of these actions covers one unit distance. These actions are represented by: walk: w, roll: r, jump: j. Each person is eligible for the trophy if they meet the following criteria :

Given an integer n, return the number of possible ways the person will be traveling n distance and be eligible for the trophy. The answer may be very large, so return it modulo 109 + 7.



Examples:

Input: 3
Output: 19
Explanation: There are in total 19 ways to travel the distance by following the rules. These 19 ways are-



  • All Walk- WWW,
  • Two Walk- WWR, WRW, RWW, WWJ, WJW, JWW,
  • One Walk- WJJ, JWJ, JJW, WJR, WRJ, RWJ, RJW, JWR, JRW,
  • Zero Walk- JJR, JRJ, RJJ

Input: 5
Output: 94
Explanation: There are in total 94 ways to travel the distance by following the rules.

Input: 7
Output: 418
Explanation: There are in total 418 ways to travel the distance by following the rules.

Approach: To solve the problem follow the below idea:

Below is the implementation of the above approach:




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
long long int mod = 1e9 + 7;
long long int dp[100001][2][3];
// dp[i][j][k] = Number of ways to travel
// distance i, with j total rolls provided
// that the person has jumped
// consecutively for the last k times
 
// Function to solve the problem
int solver(int n, int roll, int jump)
{
 
    // Base Cases: If there are more than 3 jumps
    // or 2 rolls, return 0 (no valid sequence)
    if (jump >= 3 or roll >= 2) {
        return 0;
    }
 
    // Base Case: If there are no more steps left,
    // return 1 (a valid sequence is completed)
    if (n == 0)
        return 1;
 
    // Memoization: If the solution for this
    // state is already calculated, return it
    if (dp[n][roll][jump] != -1)
        return dp[n][roll][jump];
 
    // Recursive Calls:
    // If the person chooses to walk
    int w = solver(n - 1, roll, 0);
    // If the person chooses to roll
    int r = solver(n - 1, roll + 1, 0);
    // If the person chooses to jump
    int j = solver(n - 1, roll, jump + 1);
 
    // Calculate total valid sequences, and store
    // in dp for later use
    return dp[n][roll][jump] = ((w + r) % mod + j) % mod;
}
 
// Function to initialize memoization array
// and start solving
int checkDistance(int n)
{
    // Initialize dp array with -1
    memset(dp, -1, sizeof(dp));
    // Start solving with initial parameters
    return solver(n, 0, 0);
}
 
// Main Function
int main()
{
 
    // Print the result of checkDistance(7)
    cout << checkDistance(6);
 
    return 0;
}




// Java code for the above approach:
 
class GFG {
 
    static int mod = (int)(1e9 + 7);
    static int[][][] dp = new int[100001][2][3];
    // dp[i][j][k] = Number of ways to travel
    // distance i, with j total rolls provided
    // that the person has jumped
    // consecutively for the last k times
 
    // Function to solve the problem
    static int solver(int n, int roll, int jump)
    {
 
        // Base Cases: If there are more than 3 jumps
        // or 2 rolls, return 0 (no valid sequence)
        if (jump >= 3 || roll >= 2) {
            return 0;
        }
 
        // Base Case: If there are no more steps left,
        // return 1 (a valid sequence is completed)
        if (n == 0)
            return 1;
 
        // Memoization: If the solution for this
        // state is already calculated, return it
        if (dp[n][roll][jump] != -1)
            return dp[n][roll][jump];
 
        // Recursive Calls:
        // If the person chooses to walk
        int w = solver(n - 1, roll, 0);
        // If the person chooses to roll
        int r = solver(n - 1, roll + 1, 0);
        // If the person chooses to jump
        int j = solver(n - 1, roll, jump + 1);
 
        // Calculate total valid sequences, and store
        // in dp for later use
        return dp[n][roll][jump]
            = ((w + r) % mod + j) % mod;
    }
 
    // Function to initialize memoization array
    // and start solving
    static int checkDistance(int n)
    {
        // Initialize dp array with -1
        for (int i = 0; i < 100001; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 3; k++) {
                    dp[i][j][k] = -1;
                }
            }
        }
        // Start solving with initial parameters
        return solver(n, 0, 0);
    }
 
    // Main Function
    public static void main(String[] args)
    {
        // Print the result of checkDistance(6)
        System.out.println(checkDistance(6));
    }
}
 
// This code is contributed by ragul21




# Python Implementation
mod = 10**9 + 7
dp = [[[-1 for _ in range(3)] for _ in range(2)] for _ in range(100001)]
 
def solver(n, roll, jump):
    if jump >= 3 or roll >= 2:
        return 0
     
    if n == 0:
        return 1
     
    if dp[n][roll][jump] != -1:
        return dp[n][roll][jump]
     
    w = solver(n - 1, roll, 0)
    r = solver(n - 1, roll + 1, 0)
    j = solver(n - 1, roll, jump + 1)
     
    dp[n][roll][jump] = (w + r + j) % mod
    return dp[n][roll][jump]
 
def checkDistance(n):
    return solver(n, 0, 0)
 
print(checkDistance(6))
# This code is contributed by Sakshi




// C# code for the above approach:
 
using System;
 
class GFG
{
    static int mod = (int)(1e9 + 7);
    static int[,,] dp = new int[100001, 2, 3];
    // dp[i,j,k] = Number of ways to travel
    // distance i, with j total rolls provided
    // that the person has jumped
    // consecutively for the last k times
 
    // Function to solve the problem
    static int Solver(int n, int roll, int jump)
    {
        // Base Cases: If there are more than 3 jumps
        // or 2 rolls, return 0 (no valid sequence)
        if (jump >= 3 || roll >= 2)
        {
            return 0;
        }
 
        // Base Case: If there are no more steps left,
        // return 1 (a valid sequence is completed)
        if (n == 0)
            return 1;
 
        // Memoization: If the solution for this
        // state is already calculated, return it
        if (dp[n, roll, jump] != -1)
            return dp[n, roll, jump];
 
        // Recursive Calls:
        // If the person chooses to walk
        int w = Solver(n - 1, roll, 0);
        // If the person chooses to roll
        int r = Solver(n - 1, roll + 1, 0);
        // If the person chooses to jump
        int j = Solver(n - 1, roll, jump + 1);
 
        // Calculate total valid sequences, and store
        // in dp for later use
        return dp[n, roll, jump]
            = ((w + r) % mod + j) % mod;
    }
 
    // Function to initialize memoization array
    // and start solving
    static int CheckDistance(int n)
    {
        // Initialize dp array with -1
        for (int i = 0; i < 100001; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    dp[i, j, k] = -1;
                }
            }
        }
        // Start solving with initial parameters
        return Solver(n, 0, 0);
    }
 
    // Main Function
    public static void Main(string[] args)
    {
        // Print the result of CheckDistance(6)
        Console.WriteLine(CheckDistance(6));
    }
}




const mod = 1e9 + 7;
const dp = new Array(100001).fill(null).map(() => new Array(2).fill(null).map(() => new Array(3).fill(-1)));
 
// Function to solve the problem
function solver(n, roll, jump) {
    // Base Cases: If there are more than 3 jumps
    // or 2 rolls, return 0 (no valid sequence)
    if (jump >= 3 || roll >= 2) {
        return 0;
    }
 
    // Base Case: If there are no more steps left,
    // return 1 (a valid sequence is completed)
    if (n === 0) {
        return 1;
    }
 
    // Memoization: If the solution for this state is already calculated, return it
    if (dp[n][roll][jump] !== -1) {
        return dp[n][roll][jump];
    }
 
    // Recursive Calls:
    // If the person chooses to walk
    const w = solver(n - 1, roll, 0);
    // If the person chooses to roll
    const r = solver(n - 1, roll + 1, 0);
    // If the person chooses to jump
    const j = solver(n - 1, roll, jump + 1);
 
    // Calculate total valid sequences, and store in dp for later use
    return dp[n][roll][jump] = ((w + r) % mod + j) % mod;
}
 
// Function to initialize memoization array and start solving
function checkDistance(n) {
    // Initialize dp array with -1
    for (let i = 0; i <= n; i++) {
        for (let j = 0; j < 2; j++) {
            for (let k = 0; k < 3; k++) {
                dp[i][j][k] = -1;
            }
        }
    }
 
    // Start solving with initial parameters
    return solver(n, 0, 0);
}
 
// Main Function
const result = checkDistance(6);
 
// Print the result
console.log(result);

Output
200






Time Complexity: O(n), where ‘n’ is the total distance to be travelled.
Auxiliary Space: O(n*2*3) = O(n).


Article Tags :