zoukankan      html  css  js  c++  java
  • 【洛谷】【二分答案+贪心】P1316 丢瓶盖

    【题目描述:】

    陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢?

    【输入格式:】

    第一行,两个整数,A,B。(B<=A<=100000)

    第二行,A个整数,分别为这A个瓶盖坐标。

    【输出格式:】

    仅一个整数,为所求答案。

    【算法分析:】

    关于单调性的感性证明:

      如果一个mid作为最大值时所选的瓶盖数量 x≥B,即最大值过小导致选取瓶盖过多,

      则答案一定在[mid + 1, r]内

      否则答案在[l, mid]内

    满足单调性,可以二分答案。

    关于check函数:

    在check一个数mid时,check函数返回mid作为最大值时的选取瓶盖数量,

      这里可以做一个优化,即check返回一个bool类型

      当选取的瓶盖数量超过读入的B时,直接返回1,表示二分[mid + 1, r]这个区间

    将数据从小到大排序来实现check函数:

      读入有n个元素的序列a,最大值为max

      利用贪心的思想,由于是求最少选取的瓶盖数量,能不选这个瓶盖的时候就不选

      last表示上一次选取的瓶盖位置

      当且仅当 ai - last > max 时,不选取ai会导致最大值变大,last更新成ai,选取的瓶盖个数+ 1

    关于上下界的初始化:

      二分时上下界的初始选择可以是[0, INF],最多进行31次查找。

      只选取两个瓶盖时的最大值为amax - amin ,由于数据已经排好序,上界直接初始化成 an - a1 即可

    【代码:】

     1 //丢瓶盖
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int MAXN = 100000 + 1;
     8 const int INF = 0x7fffffff;
     9 
    10 int n, m;
    11 int a[MAXN];
    12 
    13 bool check(int num) {
    14     int ret = 1, last = a[1];
    15     for(int i = 2; i <= n; i++) {
    16         if(a[i] - last > num) last = a[i], ret++;
    17         if(ret >= m) return true;
    18     }
    19     return ret >= m;
    20 }
    21 int main() {
    22     scanf("%d%d", &n, &m);
    23     int l = 0, r = INF;
    24     for(int i = 1; i <= n; i++) {
    25         scanf("%d", &a[i]);
    26     }
    27     sort(a + 1, a + n + 1);
    28     r = a[n] - a[1];
    29     while(l < r) {
    30         int mid = (l + r) >> 1;
    31         if(check(mid)) l = mid + 1;
    32         else r = mid;
    33     }
    34     printf("%d
    ", l);
    35 }
  • 相关阅读:
    flash flip 效果集
    [Chatter] : 程序设计的深度跟广度
    [Architecture Pattern] Lazy Boundary
    [ASP.NET] : 可抽换式验证来源 (DB验证建立、抽换)
    [ASP.NET] : 可抽换式验证来源 (LDAP验证、Windows验证...)
    [.NET] : 测试项目生命周期
    [Objectoriented] : 重用
    [.NET] : 自定义Configuration区段的资料写入
    [Design Pattern] : Builder vs Factory的差异点
    [Windows Forms] : 跨线程控制WinForm窗体对象
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9037063.html
Copyright © 2011-2022 走看看