二分的几种简单应用——入门

---恢复内容开始---

说起二分,最基础的二分搜索算法就不用了吧(最难的还际应用啊感觉)……实现起来很简单,搜索区间不断减半……唔……嘛……简单甩个模板好了(●‘?‘●)

下面开始学习二分的几种应用啦~~


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

一般用于求解判断条件较为简单的最大化和最小化的问题,不断缩小答案的区间。

怎么说呢……举个栗子好了

Cable master POJ - 1064

Inhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Committee has volunteered and has promised to organize the most honest contest ever. It was decided to connect computers for the contestants using a "star" topology - i.e. connect them all to a single central hub. To organize a truly honest contest, the Head of the Judging Committee has decreed to place all contestants evenly around the hub on an equal distance from it.
To buy network cables, the Judging Committee has contacted a local network solutions provider with a request to sell for them a specified number of cables with equal lengths. The Judging Committee wants the cables to be as long as possible to sit contestants as far from each other as possible.
The Cable Master of the company was assigned to the task. He knows the length of each cable in the stock up to a centimeter,and he can cut them with a centimeter precision being told the length of the pieces he must cut. However, this time, the length is not known and the Cable Master is completely puzzled.
You are to help the Cable Master, by writing a program that will determine the maximal possible length of a cable piece that can be cut from the cables in the stock, to get the specified number of pieces.Input

The first line of the input file contains two integer numb ers N and K, separated by a space. N (1 = N = 10000) is the number of cables in the stock, and K (1 = K = 10000) is the number of requested pieces. The first line is followed by N lines with one number per line, that specify the length of each cable in the stock in meters. All cables are at least 1 meter and at most 100 kilometers in length. All lengths in the input file are written with a centimeter precision, with exactly two digits after a decimal point.

Output

Write to the output file the maximal length (in meters) of the pieces that Cable Master may cut from the cables in the stock to get the requested number of pieces. The number must be written with a centimeter precision, with exactly two digits after a decimal point.
If it is not possible to cut the requested number of pieces each one being at least one centimeter long, then the output file must contain the single number "0.00" (without quotes).

Sample Input

4 11
8.02
7.43
4.57
5.39

Sample Output

2.00

题意:给出n段绳子的长度,要求割出的段数,求每段的最大长度。设bool型函数C(x):每段绳长为x时,可以割出K段绳子那么题目就变成了求x的最大值,一开始将答案的区间范围设为(0,inf)我们所要做的就是不断缩小答案所在的区间,直至区间的左右边界最接近。用二分的方法,在C(x(mid))返回true时,说明x偏小(x>=最大值),让x变大,取原区间的左区间中点继续判断;                                                  返回false时,说明x偏大,让x变小,取原区间的左区间中点继续判断直至区间缩小至最小,输出区间上界即可

不太明白为什么有的二分输出的是区间上界,有的是下界,有大佬给讲讲么

orz啊 ,WA了无数次……精度大坑啊……/(ㄒoㄒ)/~~记笔记记笔记几个关于精度的问题:①double转int的时候……记录每根绳子可以分为几段的时候crt=(int)(a[i]/x);加括号!!!不要忘了加括号!(敲黑板啊!)②关于二分的循环次数,改用for(int i=0;i<100;i++),避免eps选取不当陷入死循环的问题,100次循环可以达到1e-30的精度范围③floor(<cmath>)向下取整④double型scanf用%lf,printf用%f!!!!
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
double n,a[10005],sum;
int k;
bool C(double x)
{
    int crt=0;
    for (int i = 0; i < n; i++)
        crt +=(int)(a[i] / x);
    return crt >= k;
}
int main()
{
    while (scanf("%lf%d", &n,&k)!=EOF)
    {
        sum = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%lf",&a[i]);
        }
        double l = 0, h = 0x3f3f3f3f;
        for(int i=0;i<100;i++)
        {
            double mid = (l + h) / 2;
            if (C(mid)) l = mid;
            else h = mid;
        }
        printf("%.2f\n", floor(h * 100) / 100 );
    }
    return 0;
}

2.最大化最小值

道理跟上面差不多,最大化最小值或者最小化最大值的问题,通常可以用二分+贪心判断来解决

举个栗子,一起看一看

Aggressive cows POJ - 2456

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don‘t like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?Input

* Line 1: Two space-separated integers: N and C

* Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

* Line 1: One integer: the largest minimum distance

Sample Input

5 3
1
2
8
4
9

Sample Output

3

Hint

OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.


题意:大概就是有n个牛舍,c头牛,给出牛舍的位置,问牛舍的安排方案中,牛与牛之间最小值最大是多少

判断函数:C(d):牛与牛之间的距离不小于d

贪心:①对牛舍的位置进行排序

②第一头放入x0

③第i头牛放入xj,第i+1头放入xj+d<=xk的最小的k中

④判断是否能安排好c头牛,是→增大d;否→减小d;

#include<iostream>
#include<stdio.h>
using namespace std;
int n,c,a[100010];
bool C(int d)
{
    int t = a[0],crt=1;
    for (int i = 1; i <n; i++)
    {
        if (a[i] - t >= d)
        {
            t = a[i];
            crt++;
            if (crt >= c) return true;
        }
    }
    return false;
}
int main()
{
    while (scanf("%d%d", &n,&c)!=EOF)
    {
        for (int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        sort(a, a + n);
        int l = 0, h = a[n-1]-a[0];
        while(l<h-1)
        {
            int mid = (l + h) / 2;
            if (C(mid)) l = mid;
            else h = mid;
        }
        printf("%d\n", l );
    }
    return 0;
}


3.最大化平均值

emmmmm……这类大部分都要先推出个式子呢……虽说是对平均值进行最大化的处理,但是却很难直接判断如何处理平均值……

举个栗子,体会体会

K Best    POJ - 3111

Demy has n jewels. Each of her jewels has some value vi and weight wi.

Since her husband John got broke after recent financial crises, Demy has decided to sell some jewels. She has decided that she would keep k best jewels for herself. She decided to keep such jewels that their specific value is as large as possible. That is, denote the specific value of some set of jewels S = {i1, i2, …, ik} as

.

Demy would like to select such k jewels that their specific value is maximal possible. Help her to do so.

Input

The first line of the input file contains n — the number of jewels Demy got, and k — the number of jewels she would like to keep (1 ≤ kn ≤ 100 000).

The following n lines contain two integer numbers each — vi and wi (0 ≤ vi ≤ 106, 1 ≤ wi ≤ 106, both the sum of all vi and the sum of all wi do not exceed 107).

Output

Output k numbers — the numbers of jewels Demy must keep. If there are several solutions, output any one.

Sample Input

3 2
1 1
1 2
1 3

Sample Output

1 2


题意:给出n件物品的重量和价值,问从n件物品中取k件,取那些可以使单位重量的价值最大

唔,最容易想到的方法是,根据物品的单位重量的价值大小排序以后贪心的去取,但是这种方法是不正确的。

另外一种方法就是先确定最大的单位重量的价值(后面用s表示),然后取满足v-x*w>=0的物品。

因为最大的单位重量价值s=∑vi/∑wi(i为最优方案)>=x(其他方案的平均价值),稍作化简可以得到

∑(vi-x*wi)>=0也就是说最优方案的k件物品满足上述条件,我们只需要按每件物品的上式值排序,贪心的取前k件,判断其和是否>=0

一直在TLE……改天A了再贴代码

---恢复内容结束---

时间: 2024-08-03 05:15:49

二分的几种简单应用——入门的相关文章

Mybatis简单的入门之增删改查

一般的步骤如下 1.添加Mybatis所需要的包,和连接数据库所需的包 2.配置mybatis-config.xml文件 3.配置与pojo对应的映射文件 mybatis-config,xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http:/

简单Python入门技巧

简单Python入门技巧 Python具有丰富和强大的库.它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起.常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中[3]  有特别要求的部分,用更合适的语言改写,比如3D游戏中的图形渲染模块,性能要求特别高,就可以用C/C++重写,而后封装为Python可以调用的扩展类库.需要注意的是在您使用扩展类库时可能需要考虑平台问题,某些可能不提供跨平台的实现. Python

git简单使用入门总结

之前老早就听说过git,但是一直就没怎么去了解,之前在公司里头都是用的svn版本控制工具,然后上个月换到了新公司之后,团队里使用的是git工具,然后就专门花了点时间去了解了一番,当然期间也确实碰到了不少问题,从入职到到今天应该有快一个半月了,然后下面就是我将这一个半月以来针对git的理解使用后整理出来的一个简单入门总结. 一.安装git 我的电脑是win7系统,然后从git官网下载msysgit安装包(http://msysgit.github.io/),安装流程和一般的windows软件的安装

Python简单爬虫入门二

接着上一次爬虫我们继续研究BeautifulSoup Python简单爬虫入门一 上一次我们爬虫我们已经成功的爬下了网页的源代码,那么这一次我们将继续来写怎么抓去具体想要的元素 首先回顾以下我们BeautifulSoup的基本结构如下 #!/usr/bin/env python # -*-coding:utf-8 -*- from bs4 import BeautifulSoup import requests headers = { 'User-Agent':'Mozilla/5.0 (Win

简单的入门Android开发和Java语言基础[图]

简单的入门Android开发和Java语言基础[图]前言:去年年底到今年年初,我做过简单的智能家居,也实现过一些简单的直连和远程的智能家居.于是就将最简单的通信发布出来:智能家居简单实现-使用ESP8266简单实现和APP通讯由于这方面的资料少之又少,所以阅读量飙升的很快.也有很多人加了好友问我问题.通过问题我发现,很多都是学硬件的.或是做智能家居方面的学生,基本都不会 Android 开发的.问也有很多问我怎么学 Android 开发的.很多的人认知还是停留在学习这种软件开发技术需要去培训机构

开源TinyXML 最简单的入门教程

TinyXML是目前非常流行的一款基于DOM模型的XML解析器,简单易用且小巧玲珑,非常适合存储简单数据,配置文件. 该项目属于开源项目,在sourceforge上边的链接是:http://sourceforge.net/projects/tinyxml/ 当前最新版本是2.6.2 先看一下源码文档的结构: Docs是帮助文档,里边有非常多的使用说明,仅仅截一张图看一下: 具体根据需要再看 我们使用的是它的库,可以是静态的也可以是动态库,我就用静态库了,将这里边的几个头文件和源文件一起创建一个工

java 程序执行输出有两种简单方式

java 程序执行输出有两种简单方式: 1. System.out.println("需要输出的内容"): 该方法可参看运行一个简单的Java程序 结果图: 2. System.out.print("需要输出的内容"): 1 public class HelloWorld 2 { 3 //Java程序的入口方法,程序将从这里开始运行 4 public static void main(String[] args) 5 { 6 //向控制台打印一条语句 7 Syste

两种简单实现菜单高亮显示的JS类(转载)

两种简单实现菜单高亮显示的JS类 近期在写一个博客管理后台的前端,涉及在同一页面两种高亮显示当前菜单的需求.记得当年写静态页时,为了实现高亮都是在每个页面加不同的样式,呵.高亮显示我觉得对于web前端来说,是比较常用到的效果,正好此次又要用到,特地整理出我所写的两种高亮类. 其实思路很简单,第一种方法是通过遍历链接组的href值,通过indexOf判断href值是否被包含在浏览器当前url值中.此方法有一定局限,比如对于iframe内的菜单是不能这样判断的; 第二种方法适用范围更广一样,实现思路

Android中关于JNI 的学习(零)简单的例子,简单地入门

Android中JNI的作用,就是让Java能够去调用由C/C++实现的代码,为了实现这个功能,需要用到Anrdoid提供的NDK工具包,在这里不讲如何配置了,好麻烦,配置了好久... 本质上,Java去调用C/C++的代码其实就是去调用C/C++提供的方法,所以,第一步,我们要创建一个类,并且定义一个Native方法,如下: JniTest类: public class JniTest { public native String getTestString(); } 可以看到,在这个方法的前