Consider placing sticks from tallest to shortest. The tallest stick must be visible. For the remaining sticks, we decide where to place each one relative to previously placed sticks. If a stick is placed at the leftmost available position, it becomes visible. Otherwise, it hides behind a taller stick already placed to its left.
dfs(N, K) where N is the number of sticks remaining and K is how many still need to be visible.N == K, all remaining sticks must be visible (only one way: place them in increasing order from left), return 1.N == 0 or K == 0 (but not both), it's impossible, return 0.dfs(N-1, K-1).N-1 positions behind a taller stick: (N-1) * dfs(N-1, K).10^9 + 7.The recursive solution has overlapping subproblems. By caching results in a 2D table, we avoid redundant computation.
(n+1) x (k+1) initialized to -1.dfs(N, K), check if the result is already computed.dfs(N-1, K-1) + (N-1) * dfs(N-1, K).10^9 + 7.class Solution:
def rearrangeSticks(self, n: int, k: int) -> int:
MOD = 10**9 + 7
dp = [[-1] * (k + 1) for _ in range(n + 1)]
def dfs(N, K):
if N == K:
return 1
if N == 0 or K == 0:
return 0
if dp[N][K] != -1:
return dp[N][K]
dp[N][K] = (dfs(N - 1, K - 1) + (N - 1) * dfs(N - 1, K)) % MOD
return dp[N][K]
return dfs(n, k)Where represents the total number of sticks, and denotes the number of sticks that must be visible from the left side.
We fill the DP table iteratively from smaller subproblems to larger ones. dp[N][K] represents the number of ways to arrange N sticks with exactly K visible.
(n+1) x (k+1) initialized to 0.dp[1][1] = 1 (one stick, one visible).N from 2 to n, and each K from 1 to k:dp[N][K] = (dp[N-1][K-1] + (N-1) * dp[N-1][K]) % MODdp[n][k].class Solution:
def rearrangeSticks(self, n: int, k: int) -> int:
MOD = 10**9 + 7
dp = [[0] * (k + 1) for _ in range(n + 1)]
dp[1][1] = 1
for N in range(2, n + 1):
for K in range(1, k + 1):
dp[N][K] = (dp[N - 1][K - 1] + (N - 1) * dp[N - 1][K]) % MOD
return dp[n][k]Where represents the total number of sticks, and denotes the number of sticks that must be visible from the left side.
Each row only depends on the previous row, so we can use a 1D array and update it carefully to avoid overwriting values we still need.
k + 1.dp[1] = 1.N from 2 to n:K from 1 to k, tracking the previous value before updating.dp[K] = (prev + (N-1) * dp[K]) % MOD.dp[k].Where represents the total number of sticks, and denotes the number of sticks that must be visible from the left side.