Number of Ways to Rearrange Sticks With K Sticks Visible


Problem

There are uniquely-sized sticks whose lengths are integers from to . You want to arrange the sticks such that exactly sticks are visible from the left. A stick is visible from the left if there are no longer sticks to the left of it.

For example, if the sticks are arranged [1,3,2,5,4], then the sticks with lengths 1, 3, and 5 are visible from the left.

Given and , return the number of such arrangements. Since the answer may be large, return it modulo

Example

Input: n = 3, k = 2
Output: 3
Explanation: [1,3,2], [2,3,1], and [2,1,3] are the only arrangements such that exactly 2 sticks are visible.
The visible sticks are underlined.
Input: n = 5, k = 5
Output: 1
Explanation: [1,2,3,4,5] is the only arrangement such that all 5 sticks are visible.
The visible sticks are underlined.
Input: n = 20, k = 11
Output: 647427950
Explanation: There are 647427950 (mod 109 + 7) ways to rearrange the sticks such that exactly 11 sticks are visible.

Constraints

Submit your solution at here

Solution

Intuition

Let's say we have used up sticks labels , and we have another stick length which is smaller than all previous sticks, how can we go from here:

  • From configuration, there is only 1 way can make configuration. That is put the new stick on the front
  • From configuration, there are ways to put the new stick behind and keep the number of visible sticks the same

Approach

Let denotes the number of ways to arrange sticks and only show sticks:

  • By that definition, , there is 1 way to use nothing and show nothing

Complexity

  • Time complexity:
  • Space complexity: , could be further optimized to if necessary

Code

impl Solution {
    pub fn rearrange_sticks(n: i32, k: i32) -> i32 {
        let n = n as usize;
        let k = k as usize;
        let INF = 1000_000_007;
        let mut f = vec![vec![0i64; k+1]; n+1];
        // f[i][j] = how many ways to use i stick, and need to make j stick visible
        f[0][0] = 1;
        for j in 1..=k {
            for i in j..=n {
                // put first
                f[i][j] += f[i-1][j-1];
                // put back
                f[i][j] += f[i-1][j]*(i as i64 - 1);
                f[i][j] %= INF;
            }
        }
        return f[n][k] as i32;
    }
}