如何用贪心算法求B001区间选点最大不相交区间数?

摘要:1629 Movie Festival - CSES 最大不相交区间数 P1250 种树 - 洛谷 这两类问题的关键都是按右端点升序排序后进行处理。 最大不相交区间数 题意:给定 (n) 部电影的起始时间,问最多可以完整的看我几部? 每
1629 Movie Festival - CSES 最大不相交区间数 P1250 种树 - 洛谷 这两类问题的关键都是按右端点升序排序后进行处理。 最大不相交区间数 题意:给定 \(n\) 部电影的起始时间,问最多可以完整的看我几部? 每次选择右端点结束时间最早的区间,为剩下的区间留下更多空间。 注意题目要求区间的端点算法可行。如果区间为 [1, 3] 和 [3, 5] 答案是算两次的。而区间选点的话这里往往只选一个点,即 3 。 具体代码为 import sys from math import inf if 1: inp = lambda: sys.stdin.readline().strip() II = lambda: int(inp()) MII = lambda: map(int, inp().split()) LII = lambda: list(MII()) Max = lambda x, y: x if x > y else y Min = lambda x, y: x if x < y else y def main(): n = II() t = [] for _ in range(n): s, e = MII() t.append((s, e)) t.sort(key=lambda x: x[1]) cnt = 1 r = t[0][1] for x in t[1:]: if x[0] >= r: # 注意这里理解清楚题意 cnt += 1 r = x[1] print(cnt) if __name__ == "__main__": main() 区间选点 如果仅仅是每个区间都要有点的话,那问题就等价于最大不相交数了。否则需要额外分析。 题意:地区被分成 \(1,2,\cdots n\) 块,每块只能种一颗树。居民希望在 a, b 间至少种 \(c\) 棵树,问最少需要种多少棵树才能满足要求。 枚举每一个区间,如果当前区间没有满足需求就从右端开始种到满足需求为止。 # 模版代码直接复制即可 def main(): n = II() m = II() t = [] for _ in range(m): a, b, c = MII() t.append((a, b, c)) t.sort(key=lambda x: x[1]) used = [0] * (n + 1) ans = 0 for a, b, c in t: cnt = sum(x for x in used[a:b+1]) if cnt < c: need = c - cnt for i in range(b, a - 1, -1): if used[i] == 0: used[i] = 1 ans += 1 need -= 1 if need == 0: break print(ans) if __name__ == "__main__": main() 相关习题 H - Temperature of Bath - AtCoder 区间选点,等价于最大不相交区间数 B4399 蓝桥杯青少年组国赛 2025 第四题 - 洛谷