LevOJ P1798 求解区间覆盖问题

问题描述

用 i 来表示 xx 坐标轴上坐标为 (i1,i)、长度为 1 的区间,并给出 n (1n200) 个不同的整数,表示 n 个这样的区间。现在要求画 m 条线段覆盖住所有的区间,条件是每条线段可以任意长,但是要求所画线段的长度之和最小,并且线段的数目不超过 m(1m50)

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 }
复制代码

 

 

 

posted @   海浩河  阅读(120)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示