二分相关

Posted romalzhih

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分相关相关的知识,希望对你有一定的参考价值。

二分答案


 基本模板 
在一个有序数组中二分查找一个值 k

 1 // 在一个单调数组里面二分查找某一个值 k
 2 int n, k;
 3 int a[MAXN];
 4 
 5 void solve() 
 6     int lb = -1, ub = n;
 7     while (ub - lb > 1) 
 8         int mid = (lb + ub) / 2;
 9         if (a[mid] >= k) 
10             ub = mid;
11          else 
12             lb = mid;
13         
14     
15     printf("%d\n", ub);
16 

例题分析

POJ1064 

假定一个解并判断是否可行

题目:有 N 条绳子,长度分别为L。如果从他们中切割出 K 条长度相同的绳子的话,这 K 条绳子每条最长能有多长。答案保留到小数点后两位

解:C(x) = 可以得到 k 条长度为 x 的绳子 = floor((Li / x)的总和是否大于 k )

代码如下:

注意在程序判定中,我们的解的范围要求小数点后两位,因为 1 次循环可以将区间的范围缩小一半,100 次循环则可以达到 10-30 的精度范围。除此之外,也可以把中止条件设为像 (ub - lb)> EPS 这样,指定一个区间的大小

 1 int N, K; 
 2 double L[MAXN];
 3 
 4 bool C(double x) 
 5     int num = 0;
 6     for (int i = 0; i < N; i++) 
 7         num += (int)(L[i] / x);
 8     
 9     return num >= K;
10 
11 
12 void solve() 
13     // 初始化解的范围
14     double lb = 0, ub = INF * 1.0;
15 
16     // 重复循环,直到解的范围足够小
17     for (int i = 0; i < 100; i++) 
18         double mid = (lb + ub) / 2;
19         if (C(mid))
20             lb = mid;
21         else
22             ub = mid;
23     
24     printf("%.2f\n", floor(ub * 100) / 100);
25 
26 
27 int main() 
28 #ifndef ONLINE_JUDGE
29     freopen("input.txt", "r", stdin);
30 #endif
31     scanf("%d %d", &N, &K);
32     for (int i = 0; i < N; i++) scanf("%lf", &L[i]);
33     solve();
34     return 0;
35 

POJ 2456 

最大化最小值

题目:

农夫约翰打了一间有 N 间牛舍的小屋。牛舍排在一条线上,第 i 号牛舍在 x_i 的位置。但是他的 M 头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间的互相伤害,因此决定把每头牛都放在离其他牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。

解:

C(d)= 可以安排牛的位置使得最近的两头牛的距离不小于 d。则问题转化为求最大的 d

贪心:

对牛舍的位置进行排序;

把第一头牛放入 $x_0$ 的牛舍;

如果第 i 头牛放入了 $x_j$ 的话,第 $i+1$ 头牛就要放入满足 $x_j+d<=x_k$ 的最小的 $x_k$ 中

 1 int N, M;
 2 int x[MAXN];
 3 
 4 bool C(int d) 
 5     int last = 1;
 6     for (int i = 1; i < M; i++) 
 7         int crt = last + 1;
 8         while (crt <= N && x[crt] - x[last] < d) 
 9             crt++;
10         
11         if (crt == N + 1) return false;
12         last = crt;
13     
14     return true;
15 
16 
17 void solve() 
18     sort(x + 1, x + 1 + N);
19     int lb = 0, ub = INF;
20     while (ub - lb > 1) 
21         int mid = (ub + lb) / 2;
22         if (C(mid))
23             lb = mid;
24         else
25             ub = mid;
26     
27     printf("%d\n", lb);
28 
29 
30 int main() 
31 #ifndef ONLINE_JUDGE
32     freopen("input.txt", "r", stdin);
33 #endif
34     scanf("%d %d", &N, &M);
35     for (int i = 1; i <= N; i++) scanf("%d", &x[i]);
36     solve();
37     return 0;
38 

 

以上是关于二分相关的主要内容,如果未能解决你的问题,请参考以下文章

二分图部分总结

二分图相关问题

算法题16 二分查找及相关题目

二分相关

二分查找相关算法

浅谈二分答案的原理和相关应用