We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Number of Sets of K Non-Overlapping Line Segments

Difficulty: Medium


Problem Description

Given n points on a 1-D plane, where the i-th point (from 0 to n-1) is at x = i, find the number of ways we can draw exactly k non-overlapping line segments such that each segment covers two or more points. The endpoints of each segment must have integral coordinates. The k line segments do not have to cover all n points, and they are allowed to share endpoints. Return the number of ways we can draw k non-overlapping line segments modulo 10^9 + 7.


Key Insights

  • Each line segment must cover at least two points, which means the minimal length of a segment is 1.
  • Line segments can share endpoints, allowing for overlaps in the segments themselves.
  • The problem can be approached using dynamic programming to count the valid combinations of segments.

Space and Time Complexity

Time Complexity: O(n^2 * k)
Space Complexity: O(n * k)


Solution

The solution involves using dynamic programming to build a table where dp[i][j] represents the number of ways to draw j non-overlapping line segments using the first i points.

  1. Initialize a 2D array dp of size (n+1) x (k+1) with all values set to 0.
  2. Set dp[0][0] = 1 as the base case (one way to draw 0 segments with 0 points).
  3. For each number of points from 2 to n, iterate through the number of segments from 1 to k.
  4. For each segment, calculate the number of valid ways to form segments from previous points and update the dp table accordingly.
  5. Use cumulative sums to efficiently compute the total number of ways to create segments without overlapping.

This approach ensures that we consider all possible segment configurations while adhering to the constraints given in the problem.


Code Solutions

def count_segments(n, k):
    MOD = 10**9 + 7
    dp = [[0] * (k + 1) for _ in range(n + 1)]
    dp[0][0] = 1

    for i in range(2, n + 1):
        for j in range(1, k + 1):
            dp[i][j] = dp[i - 1][j]  # Not using the i-th point
            for m in range(1, i):
                dp[i][j] += dp[m - 1][j - 1]
                dp[i][j] %= MOD

    return dp[n][k]

# Example usage
print(count_segments(4, 2))  # Output: 5
← Back to All Questions