• 蓝桥杯 第 2 场算法双周赛 第3题 摆玩具【算法赛】 c++ 贪心


     题目

    摆玩具【算法赛】icon-default.png?t=N7T8https://www.lanqiao.cn/problems/5888/learning/?contest_id=145

    问题描述

    小蓝是一个热爱收集玩具的小伙子,他拥有 n 个不同的玩具。

    这天,他把 n 个玩具按照高度顺序从矮到高摆放在了窗台上,然后,他希望将这些玩具分成 k 个段,使得所有分段的极差之和尽可能小。

    具体来说,你需要将一个长度为 n 的序列分为 k 段,我们定义 Gi​ 为第 i 个分段的极差,你要最小化 ∑i=1k​Gi​。

    你能帮助小蓝找到最小值是多少吗?

    极差:是指每个分段中最高和最矮玩具高度之差,例如有一段为:{3,6,10,12}{3,6,10,12},那么极差为 12−3=912−3=9。

    分段:即每一段在原始序列中是一段连续区间,例如将 {1,2,3,4,5}{1,2,3,4,5} 分为两段,{1,2,3}∣{4,5}{1,2,3}∣{4,5} 是合法的,但是 {1,2,4}∣{3,5}{1,2,4}∣{3,5} 不是合法的。

    输入格式

    第一行输入两个整数 n,k,代表玩具数量和需要分段的数量。

    第二行输入 n 个整数 {h1​,h2​,...,hn​},代表每个玩具的高度。

    输出格式

    输出一个整数,表示最小的极差和。

    样例输入

    1. 5 2
    2. 2 5 7 10 13

    样例输出

    8
    

    说明

    存在多种分段方式,其结果都是最小值:

    1. {2}∣{5,7,10,13}{2}∣{5,7,10,13},极差和为 0+8=80+8=8。
    2. {2,5,7}∣{10,13}{2,5,7}∣{10,13},极差和为 5+3=85+3=8。
    3. {2,5,7,10}∣{13}{2,5,7,10}∣{13},极差和为 8+0=88+0=8。

    不存在其他方案使得答案小于 88。

    评测数据范围

    1≤k≤n≤105 。

    1≤h1​≤h2​≤h3​≤...≤hn​≤109 。

    运行限制

    语言最大运行时间最大运行内存
    C++1s128M
    C1s128M
    Java2s128M
    Python33s128M
    PyPy33s128M

    思路和解题方法

    1. #include #include :这两行代码包含了所需的头文件,分别用于输入输出操作和排序操作。

    2. int n;int k, a[100005],b[100005];:这部分代码定义了三个整型变量nk和两个整型数组ab。其中,n表示序列中元素的数量,k表示要删除的元素的数量,a保存原始序列中的元素,b保存相邻元素之间的差值。

    3. void solve():这部分代码定义了一个函数solve,用于解决问题。

    4. cin >> n >> k;:使用输入流cin读取用户输入的序列长度n和要删除的元素数量k

    5. for (int i = 0; i < n; i++) cin >> a[i];:使用循环结构for,依次读取用户输入的序列中的元素,并将它们存储在数组a中。

    6. for (int i = 1; i < n; i++) b[i-1]=a[i]-a[i-1];:使用循环结构for,计算相邻元素之间的差值,并将它们存储在数组b中。注意,数组b的下标从0开始。

    7. sort(b,b+n-1);:使用sort函数,对数组b中的元素进行排序。由于数组b中只有n-1个元素,所以第二个参数为n-1

    8. int sum=0; for(int i=0;i:使用循环结构for,计算前n-k个最小的差值之和,并将结果存储在变量sum中。

    9. cout << sum;:使用输出流cout将结果输出到控制台。

    10. int main():这部分代码定义了主函数main,是程序的入口点。

    11. solve();:调用函数solve解决问题。

    12. return 0;:返回0表示程序正常结束。

    复杂度

            时间复杂度:

                    O(n*logn)

    时间复杂度分析:

    1. 输入序列的长度为n,需要遍历n个元素,所以输入的时间复杂度为O(n)。
    2. 计算相邻元素之间的差值并存储到数组b中,需要遍历n-1个元素,所以该步骤的时间复杂度为O(n)。
    3. 对数组b进行排序,排序的时间复杂度为O(nlogn)。
    4. 计算前n-k个最小差值的和,需要遍历n-k个元素,所以该步骤的时间复杂度为O(n)。
    5. 输出结果的时间复杂度为O(1)。

    代码的总时间复杂度为O(nlogn)。

            空间复杂度:

                    O(n)

    空间复杂度分析:

    1. 数组a和数组b的长度都为n,所以它们的空间复杂度均为O(n)。
    2. 其他变量占用的空间可以忽略不计。

    c++ 代码

    1. #include
    2. #include
    3. using namespace std;
    4. int n; // 存储序列的长度
    5. int k, a[100005], b[100005]; // k表示要删除的元素数量,a存储原始序列的元素,b存储相邻元素的差值
    6. void solve() {
    7. cin >> n >> k; // 输入序列的长度和要删除的元素数量
    8. for (int i = 0; i < n; i++)
    9. cin >> a[i]; // 输入序列的元素并存储到数组a中
    10. // 计算相邻元素之间的差值并存储到数组b中
    11. for (int i = 1; i < n; i++)
    12. b[i-1] = a[i] - a[i-1];
    13. sort(b, b+n-1); // 对数组b进行排序
    14. int sum = 0;
    15. for (int i = 0; i < n-k; ++i) {
    16. sum += b[i]; // 计算前n-k个最小差值的和
    17. }
    18. cout << sum; // 输出结果
    19. }
    20. int main() {
    21. solve(); // 调用solve函数解决问题
    22. return 0;
    23. }

    觉得有用的话可以点点赞,支持一下。

    如果愿意的话关注一下。会对你有更多的帮助。

    每天都会不定时更新哦  >人<  。

  • 相关阅读:
    【华为校招】【校招】【Java】考古问题
    动态规划(树形dp)
    C++基础——this指针
    AppLink上的小鹅通能实现什么操作呢?
    java中的set集合[69]
    Go 之 captcha 生成图像验证码
    elementUi里的时间选择器显示默认时间为0点并将标准格式转换为xxxx年xx月xx日 xx时xx分xx秒
    vue的hook(钩子函数)
    Android开发-视图view讲解
    Pytorch:cat、stack、squeeze、unsqueeze的用法
  • 原文地址:https://blog.csdn.net/jgk666666/article/details/134038957