Number of Ways to Stay in the Same Place After Some Steps

hard dp counting

Problem

A pointer starts at index 0 of an array of length arrLen. In one step it may move one slot left, one slot right, or stay put, but it must never leave the array. Given steps total moves, count how many distinct move sequences return the pointer to index 0 at the end. Return the count modulo 109 + 7.

Inputsteps = 3, arrLen = 2
Output4
The four sequences are: Stay-Stay-Stay, Stay-Right-Left, Right-Left-Stay, and Right-Stay-Left. Each ends back at index 0.

def num_ways(steps, arr_len):
    MOD = 10**9 + 7
    width = min(arr_len, steps // 2 + 1)
    dp = [0] * width
    dp[0] = 1
    for _ in range(steps):
        nxt = [0] * width
        for p in range(width):
            total = dp[p]
            if p > 0:
                total += dp[p - 1]
            if p + 1 < width:
                total += dp[p + 1]
            nxt[p] = total % MOD
        dp = nxt
    return dp[0]
function numWays(steps, arrLen) {
  const MOD = 1000000007n;
  const width = Math.min(arrLen, Math.floor(steps / 2) + 1);
  let dp = new Array(width).fill(0n);
  dp[0] = 1n;
  for (let s = 0; s < steps; s++) {
    const nxt = new Array(width).fill(0n);
    for (let p = 0; p < width; p++) {
      let total = dp[p];
      if (p > 0) total += dp[p - 1];
      if (p + 1 < width) total += dp[p + 1];
      nxt[p] = total % MOD;
    }
    dp = nxt;
  }
  return Number(dp[0]);
}
class Solution {
    public int numWays(int steps, int arrLen) {
        long MOD = 1000000007L;
        int width = Math.min(arrLen, steps / 2 + 1);
        long[] dp = new long[width];
        dp[0] = 1;
        for (int s = 0; s < steps; s++) {
            long[] nxt = new long[width];
            for (int p = 0; p < width; p++) {
                long total = dp[p];
                if (p > 0) total += dp[p - 1];
                if (p + 1 < width) total += dp[p + 1];
                nxt[p] = total % MOD;
            }
            dp = nxt;
        }
        return (int) dp[0];
    }
}
int numWays(int steps, int arrLen) {
    const long long MOD = 1000000007LL;
    int width = min(arrLen, steps / 2 + 1);
    vector<long long> dp(width, 0);
    dp[0] = 1;
    for (int s = 0; s < steps; s++) {
        vector<long long> nxt(width, 0);
        for (int p = 0; p < width; p++) {
            long long total = dp[p];
            if (p > 0) total += dp[p - 1];
            if (p + 1 < width) total += dp[p + 1];
            nxt[p] = total % MOD;
        }
        dp = nxt;
    }
    return (int) dp[0];
}
Time: O(steps · min(arrLen, steps)) Space: O(min(arrLen, steps))