Given n points on a 1-D plane, where the ith point (from 0 to n-1) is at x = i, find the number of ways we can draw exactlyknon-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 drawknon-overlapping line segments_._ Since this number can be huge, return it modulo10^9 + 7.
Input: n =4, k =2Output: 5Explanation: The two line segments are shown in red and blue.The image above shows the 5 different ways {(0,2),(2,3)},{(0,1),(1,3)},{(0,1),(2,3)},{(1,2),(2,3)},{(0,1),(1,2)}.
Input: n =30, k =7Output: 796297179Explanation: The total number of possible ways to draw 7 line segments is3796297200. Taking this number modulo 109+7 gives us 796297179.
We need to count the number of ways to draw k non-overlapping segments on n points, where each segment covers at least two points. This is a classic combinatorial DP problem, where we can use DP to count the ways by considering whether to start a segment at each point or not.
classSolution {
staticfinalint MOD = 1000000007;
publicintnumberOfSets(int n, int k) {
int[][] dp =newint[n+1][k+1];
for (int i = 0; i <= n; i++) dp[i][0]= 1;
for (int seg = 1; seg <= k; seg++) {
for (int i = seg*2; i <= n; i++) {
for (int j = seg*2-1; j < i; j++) {
dp[i][seg]= (dp[i][seg]+ dp[j][seg-1]) % MOD;
}
}
}
return dp[n][k];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution {
privateval MOD = 1000000007funnumberOfSets(n: Int, k: Int): Int {
val dp = Array(n+1) { IntArray(k+1) }
for (i in0..n) dp[i][0] = 1for (seg in1..k) {
for (i in seg*2..n) {
for (j in seg*2-1 until i) {
dp[i][seg] = (dp[i][seg] + dp[j][seg-1]) % MOD
}
}
}
return dp[n][k]
}
}
1
2
3
4
5
6
7
8
9
10
defnumberOfSets(n: int, k: int) -> int:
MOD =10**9+7 dp = [[0]*(k+1) for _ in range(n+1)]
for i in range(n+1):
dp[i][0] =1for seg in range(1, k+1):
for i in range(seg*2, n+1):
for j in range(seg*2-1, i):
dp[i][seg] = (dp[i][seg] + dp[j][seg-1]) % MOD
return dp[n][k]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
constMOD: i32=1_000_000_007;
impl Solution {
pubfnnumber_of_sets(n: i32, k: i32) -> i32 {
let n = n asusize;
let k = k asusize;
letmut dp =vec![vec![0; k+1]; n+1];
for i in0..=n { dp[i][0] =1; }
for seg in1..=k {
for i in seg*2..=n {
for j in seg*2-1..i {
dp[i][seg] = (dp[i][seg] + dp[j][seg-1]) %MOD;
}
}
}
dp[n][k]
}
}