二分题目

题目背景

一年一度的“跳石头”比赛又要开始了!

题目描述

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选

择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终 点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达 终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳 跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能 移走起点和终点的岩石)。

刚开始看好久,典型的最小值最大化的问题,知道用二分,但是不知道如何判断条件,参考网上的,明白了。

二分判断最小距离的最大值。

将与起点距离为 2 和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。

代码如下:

package demo2;

import java.util.*;

public class Main {

    public static boolean check(int x,int m,int a[],int w){
     int sum=0, next =0;
     for(int i=1;i<=m;i++){
         if(a[i]-next<x)
             sum++;      //判断是否i和上一个标记的石头距离比x小,如果小可以移除否则保留石头继续下一个
         else
             next= a[i];
     }     if(sum>w)      //如果移除的石头比要求移除的多的话,则返回false
             return false;

     return true;
    }
//    static int inf =10000000;
    public static void main(String[] args) {
         Scanner sc = new Scanner(System.in);
         int n = sc.nextInt();
         int m = sc.nextInt();
         int w = sc.nextInt();
        int[] a= new int[m+2];
         for(int i=1;i<=m;i++)
             a[i]=sc.nextInt();
         a[++m]=n;
          int l =0,r = n;
          int mid=0;
          int ans=0;
          while(l<=r){
               mid = (r+l)/2;
              if(check(mid,m,a,w)){
                 ans=mid;l=mid+1; }
              else
                  r=mid-1;
       }
          System.out.println(ans);
    }
}

最小值最大化

给定长度为N的序列A,其中1≤N≤100000,1≤A[i] ≤100000。现在要将A分成M段(1≤M≤N),每段有A中的1个或相邻的多个元素构成。例如A={1,3,4,6,7,8}分成3段的一种情况为B={1,(3,4),(6,7,8)}。 
由于将A分成M段的情况有多种,现在要求最大子段和最小的情况。例如上述中B的子段和分别为{1,7,21}.

import java.util.*;

public class Main {

    public static boolean check(int x,int m,int a[] ){
      int sum=0;int ans=1;
        for(int i=0;i<a.length;i++)
      {    sum+=a[i];
        if(sum>x)
        {    ans++;
            sum=a[i];
        }
      }
        if(ans>m)
            return true;
        else
            return false;
    }
//    static int inf =10000000;
    public static void main(String[] args) {
         Scanner sc = new Scanner(System.in);
         int n = sc.nextInt();
         int m = sc.nextInt();

        int[] a= new int[m+2];int t=0;
         for(int i=0;i<n;i++)
         { a[i]=sc.nextInt();
             if(t<a[i])
                 t=a[i];
         }
          int l =0,r = t;
          int mid=0;
          int ans=0;
          while(l<=r){
               mid = (r+l)/2;
              if(check(mid,m,a)){
                 l=mid+1; }
              else{
                  ans=mid; r=mid-1;
       }}
          System.out.println(ans);
    }
}

原文地址:https://www.cnblogs.com/ls-pankong/p/10480581.html

时间: 2024-08-06 06:26:36

二分题目的相关文章

二分题目总结

在UVA上搜索二分时搜到了一个很好的public专题 1.POJ - 3258 River Hopscotch http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16277 解题思路:http://blog.csdn.net/l123012013048/article/details/45646911 这题是符合条件的情况下,解有可能是偏小的 2.POJ - 3273 Monthly Expense http://acm.hu

二分题目总结(未完待续)

二分的用处太大了,不管是求简单的方程,还是求最优解方面都是不错的解题思想. 只要在线性,顺序或者有序的数据里就可以用二分来找最优的答案,而且时间平均都是O(log2 n).题目中好像是HDU 4190吧,这题的限时是10000ms,而用二分做才用时1000ms,其优点可想而知. 不过就像<编程珠玑>中说的一样,虽然二分思路及其做法很爽,但是编写二分的程序总是错漏百出的.二分的第一个程序出现在1942年,但是直到1962年出出现了第一个没有bug的二分程序,其编写正确难度可想而知. 解题技巧:

二分 题目 压缩打包 Special Judge? 不不不 当然不是

http://noi.openjudge.cn/ch0111/ No 题目 分数 01 查找最接近的元素 10 3176 02 二分法求函数的零点 10 2181 03 矩形分割 10 1420 04 网线主管 10 1648 05 派 10 1581 06 月度开销 10 1449 07 和为给定数 10 1906 08 不重复地输出数 10 1790 09 膨胀的木棍 10 768 10 河中跳房子 10 2027 ------------------------------萌萌的分割线--

UVA10183 - How Many Fibs?(java大数+二分)

UVA10183 - How Many Fibs?(java大数+二分) 题目链接 题目大意:给你a,b,求[a,b]之间有多少个fibs数. 解题思路:虽然a.b很大,但是在10^100内的fibs却不超过500个.这样就可以先把这些fibs保存在数组中,然后每次二分去找a,b的位置,然后就可以得到之间有多少个fibs. 代码: import java.util.*; import java.math.*; import java.io.*; import java.lang.String.*

POJ 3621(0/1分数规划,二分) Sightseeing Cows

题意 给一个n个点m条边的图,每一个点和每一条边都有权值.现在要找一个环的点权和/边权和最大,求这个最大值. 思路 SPFA+二分 题目的关系式:点权和/边权和 <= ans 转换一下就变成 ans*边权和 - 点权和 >= 0; 二分答案,然后用SPFA去check是否存在一个负权回路. 参考code: /* #pragma warning (disable: 4786) #pragma comment (linker, "/STACK:0x800000") */ #in

[SinGuLaRiTy] 分治题目复习

[SInGuLaRiTy-1025] Copyrights (c) SinGuLaRiTy 2017. All Rights Reserved. [POJ 1905] 棍的扩张 (Expanding Rods) 题目描述 已知一根长为L的细棍被加热了n摄氏度,那么其新的长度为L'=(1+n*C)*L.中间的C是热膨胀系数.当一根细棍被夹在两面墙中间然后被加热,它会膨胀,其形状会变成一个弧,而原来的细棍(加热前的细棍)就是这个弧所对的弦.你的任务是计算出弧的中点与弦的中点的距离. 输入 包含多组数

UVA10277 - Boastin&#39; Red Socks(枚举+二分)

UVA10277 - Boastin' Red Socks(枚举+二分) 题目链接 题目大意:现在有m只红袜子,n只黑袜子,这样总袜子total = n + m;现在给你p, q,确定n和m,使得从这些袜子中取两只都是红袜子的概率等于p/q:如果没有这样的n和m满足要求输出impossible; 解题思路:m *(m - 1) / (total * (total - 1)) = p /q; 那么我们只需要枚举total,就可以解到m.但是会有精度误差,貌似有解决的办法,但是觉得没法理解.后面看了

CUGBACM_Summer_Tranning3 2013长沙现场赛(二分+bfs模拟+DP+几何)

A题:二分 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4791 用lower_bound可以轻松解决,不过比赛的时候逗逼了. 刚开始没有预处理,所以队友给出一组数据的时候没通过,然后一时紧张又想不出什么好的解决办法,所以就没再继续敲代码.实在有点可惜了. #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #includ

LightOJ 1088 Points in Segments 二分查找

1088 - Points in Segments PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Given n points (1 dimensional) and q segments, you have to find the number of points that lie in each of the segments. A point pi will lie in a segme