LevOJ P1798 求解区间覆盖问题
问题描述
用 i 来表示 xx 坐标轴上坐标为 (i−1,i)、长度为 1 的区间,并给出 n (1≤n≤200) 个不同的整数,表示 n 个这样的区间。现在要求画 m 条线段覆盖住所有的区间,条件是每条线段可以任意长,但是要求所画线段的长度之和最小,并且线段的数目不超过 m(1≤m≤50)。
Tip: 本题为单组输入
输入描述
第 1 行表示区间个数 n 和所需线段数 m, 第 2 行表示 n 个点的坐标。
输出描述
一行,输出 m 条线段的最小长度和。
样例输入
5 3
1 3 8 5 11
样例输出
7
一开始想了很久也没有思路,后来大概有点思路,就是要尽可能地减少大空当,就是贪心,怎么贪呢,一开始的思路是拼接,即先用单个线条去覆盖产生最大空当的区间,自以为正确,后来发现覆盖了该区间后,可能会产生更大的区间。
去看题解,发现其实已经很接近答案了。
正确的题解就是贪心,最简单的情况就是m大于n,答案直接就是n,还有一种情况是m小于n,也就是主要情况。
我们先假想所有的区间用一段线段覆盖,那么接下来怎么取使线段和最小呢,我们假设position[0]和position[1]之间的空当最大,那么下一条线段应该就在这两端之间,即两条线段在这边空开。之后的思路也是一样,贪心地在区间中找到最大空当。
图片源自https://blog.csdn.net/qq_45666654/article/details/105506144
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 #define N 202 5 int a[N], gap[N]; 6 bool compare(int a, int b) 7 { 8 return a > b; 9 } 10 int main() 11 { 12 int n, m; 13 cin >> n >> m; 14 for (int i = 0; i < n; i++) 15 cin >> a[i]; 16 if (m >= n) 17 { 18 cout << n << endl; 19 return 0; 20 } 21 sort(a, a + n); 22 int s = a[n - 1] - a[0] + 1; 23 for (int i = 0; i < n - 1; i++) 24 gap[i] = a[i + 1] - a[i] - 1; 25 sort(gap, gap + n - 1, compare); 26 int i = 1; 27 while (i < m) 28 { 29 s -= gap[i - 1]; 30 i++; 31 } 32 cout << s << endl; 33 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App