当前位置:   article > 正文

学习小组--算法笔试模拟题精解_分组 题目描述 现在一共有n个学生,每个学生有一个考试能力值。现在希望把这些学生

分组 题目描述 现在一共有n个学生,每个学生有一个考试能力值。现在希望把这些学生

题目描述

在一个课堂上,有 n 个学生 (1<=n<=3e5),每个学生都有他们自己的学分ai(1<=ai<=1e9,ai<=ai-1),现在老师想将他们分为 m 个小组 (1<=m<=n),为了方便交流,所有的小组都是由相邻的学生组成 (abc 相邻 , 不存在 ac 一个小组 b 在另一个小组的情况 ),现在老师想让每个小组的学分差值尽量小 ( 最大值减去最小值 ),请你帮助老师来分一下组,输出最后的每个小组的最小的差值的总和。
第一行和第二行输入两个数 n、m 表示有 n 个学生要分成 m 个小组,再输入 n个数,表示每个学生的学分。
输出一个数字,表示最后分出的 m 个小组的最小的差值的总和。
示例 1
输入:
5
3
[1,3,5,7,9]
输出:
4

解题方法:

因为题目中说了 ai 是一个非递减的数列,所以我们可以推导出一个式子。
比如我们要将一个数组分成 3 组,那么可以假设为,[a1,ai],[ai+1,aj],[aj+1,an]这三组,然后我们所要求的值就是 (ai - a1) + (aj - ai+1) + (an - aj+1) .
那么就可以推导出 an - a1 + aj - aj+1 - ai - ai+1,所以就是 an - a1 减去最大的 m-1 个相邻的差值,那么 ai-ai+1 这个显然是差分的性质,所以我们对于原数列求一个差分数组出来,然后对差分数组进行排序,贪心的去减去前 m-1 个最大的就好了。

/**
     * 学习小组
     * @param n n 个学生
     * @param m 分成 m 个小组
     * @param nums 表示每个学生的学分
     * @return
     */
    public int solution(int n, int m, int[] nums) {
        int[] sub = new int[n-1];
        for(int i = 0; i < (n-1); i++){
           sub[i] = nums[i+1] - nums[i];
        }
        Arrays.sort(sub);
        int ans = nums[n-1] - nums[0];
        for(int i = 0;i< (m-1) ;i++){
            ans = ans - sub[n-2-i];
        }
        return ans;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号