题目:将n个同学分为k个队伍,使队伍的极差最小并返回最小的极差
不断检查是否能将n个同学分为<=k个队伍,如果可以缩减右边界(右边界是极差)
如果不行,扩大左边界(mid+1)
假设 cnt 为贪心得到的解,ans 为整体最优解,因为一定可以把一个组分成多个组,所以满足 cnt >= ans 的条件,而排序之后在每组最大差值既定的条件下,贪心会尽可能把符合条件的同学收入到一个组里,直至装不了才会开一个新组,便满足 cnt <= ans 的条件。然后就可以得到 cnt == ans 的结论,所以贪心就是整体最优解。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool check(vector<int>& heights, int k, int max_diff) {
int cnt = 1, cur = heights[0], n = heights.size();
for (int i = 1; i < n; i++)
{
if (heights[i] - cur > max_diff)//如果超过设定边界就要开新队伍
{
cnt++;
cur = heights[i];
}
}
return cnt <= k; //队伍总数符合要求吗?
}
int main() {
int n, k;
cin >> n >> k;
vector<int> heights(n);
for (int i = 0; i < n; ++i) cin >> heights[i];
sort(heights.begin(), heights.end());
int l = 0, r = heights[n - 1] - heights[0];//左闭右开的区间
while (l < r)
{
int mid = l + (r - l) / 2;
if (check(heights, k, mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
return 0;
}
贪心贪心,贪的是队伍极差,不断将队伍极差缩小来取到最小

284

被折叠的 条评论
为什么被折叠?



