题目链接:sdut-3916 上色的纱雾
题目解法:
二分搜索合适的答案,并不断往小了更新答案。因为往小了更新答案与向下搜索答案都需要bisearch(l, len),而 < m时更新答案不影响结果,因为必有最小的ans是满足cnt == m的,所以两步在bisearch()中并做一步。
时间复杂度: O(log(lenmax))
AC代码1:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int n, m;
int dot[maxn];
int ans;
void bisearch(int l, int r);
int main(void)
{
while (scanf("%d%d", &n, &m) == 2)
{
for (int i = 0; i < n; i++)
scanf("%d", &dot[i]);
sort(dot, dot + n);
bisearch(0, dot[n - 1] - dot[0] + 1);
printf("%d\n", ans);
}
return 0;
}
void bisearch(int l, int r)
{
if (l >= r)
return ;
int len = (l + r) / 2;
int i = 0;
int cnt = 0;
while (i < n && cnt < m)
{
cnt++;
int p = dot[i];
while (i < n && dot[i] <= p + len)
i++;
}
if (i == n && cnt <= m) //<m时更新答案不影响结果,因为必有最小的ans满足cnt == m;
{
ans = len;
bisearch(l, len);
}
else
bisearch(len + 1, r);
}
/***************************************************
User name: Herman_lien
Result: Accepted
Take time: 448ms
Take Memory: 340KB
Submit time: 2017-06-08 16:59:22
****************************************************/
自己也想过用区间覆盖的方法(贪心)做,但后来发现完全不是那么回事。。。那个是求最小的m段区间长度和,而这是求分成m段能得到的最小的最大区间长度。这种题目应该采用的多是二分枚举答案的方法吧,方便又快捷~
本文介绍了解决SDUT-3916上色的纱雾问题的一种方法,通过使用二分搜索来寻找最优解。具体地,该算法能够有效地找到将序列分割为m段时的最小最大区间长度。

1239

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



