二分答案 [TJOI2007]路标设置

本人水平有限,题解不到为处,请多多谅解

本蒟蒻谢谢大家观看

题目:https://www.luogu.org/problem/P3853

因为数据n<=10000000;通过样例分析即可得出这是一到二分题。

样例解析:将一段区间分成(k+n)段,找出(k+n)的一段最大值。因为k不确定,所以如何分也不确定,我们就是要找出这段最大值在整个若干次情况中与其余一段最大值比较,取这些里面最小的。

本题是一道二分答案的模板题,只需注意一下细节即可

code:

#include<bits/stdc++.h>
//#pragma GCC optimize(3)
int l,n,k,a[110000],dis[110000],ans=0,kk,mm,yzl;
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch<=‘9‘&&ch>=‘0‘){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
bool check(int mid)//判断是否可以继续二分下去
{
    int num=0;
    for(int i=1;i<n;i++)
    {
            num+=dis[i]/mid;
        //因为本题总是一条直线 即:0~len  mid不断二分,最终统计几个 1/2
    }
    if(num>k)return 0;
    return 1;
}
int main()
{
    int ls,mid,rs;
    l=read(),n=read(),k=read();
    for(int i=1;i<=n;i++)
    a[i]=read();
    for(int i=1;i<n;i++){
    dis[i]=a[i+1]-a[i]-1;
    //必须要减一,因为这是一个间隔问题,其保证起始点与终止点都已设路标
    //只需要把中间的部分进行均匀分配
    }
    ls=0;rs=l;
    while(ls<=rs){
        mid=ls+rs>>1;
        if(check(mid)){
            rs=mid-1;
            yzl=mid;
        }
        else{
            ls=mid+1;
        }
    }
    printf("%d\n",yzl);//此时mid==ls,也可以直接输出ls
    return 0;
}
/*
9 2 2
0 8

3
*/

原文地址:https://www.cnblogs.com/nlyzl/p/11357097.html

时间: 2024-08-29 00:59:05

二分答案 [TJOI2007]路标设置的相关文章

luogu P3853 [TJOI2007]路标设置 |二分

题目背景 B市和T市之间有一条长长的高速公路,这条公路的某些地方设有路标,但是大家都感觉路标设得太少了,相邻两个路标之间往往隔着相当长的一段距离.为了便于研究这个问题,我们把公路上相邻路标的最大距离定义为该公路的"空旷指数". 题目描述 现在政府决定在公路上增设一些路标,使得公路的"空旷指数"最小.他们请求你设计一个程序计算能达到的最小值是多少.请注意,公路的起点和终点保证已设有路标,公路的长度为整数,并且原有路标和新设路标都必须距起点整数个单位距离. 输入格式 第

P3853 [TJOI2007]路标设置

传送门 思路: 类似于数列分段的二分查找答案.设目前的 mid 是一个最小的“空旷指数”,那么在 sum 数组(路标数组)里每两个相邻间的路标距离一定要小于等于目前的 mid , 如果大于,那就必须使用一些路标去填补这个距离. 两个路标之间距离大于 mid 又要分为两种情况:①两路标之间距离不能整除 mid ,则要放置 ( sum [ i+1 ] -sum [ i ] )/mid 个路标.②如果两路标之间距离能够整除 mid 则所放置的路标数要 -1 . 每一次二分判断 mid 距离是否满足 c

题解 P3853 【[TJOI2007]路标设置】

#include<bits/stdc++.h> using namespace std; int l,r,len,n,k,maxx,a[100005]; //通过计算可以发现 对一个给定的距离len而言 中间分成若干个长度不大于x的段的个数为 len/x 如果len为x的倍数 则为len/x-1 bool check(int x){ int tmp=0; for (int i=2;i<=n;i++){ tmp+=(a[i]-a[i-1])/x; if ((a[i]-a[i-1])%x==

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

HDU3081Marriage Match II(二分答案+并查集+最大流SAP)经典

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2507    Accepted Submission(s): 856 Problem Description Presumably, you all have known the question of stable marriage match. A

Codeforce 371C Hamburgers (二分答案)

题目链接 Hamburgers 二分答案,贪心判断即可. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define LL long long 7 8 char str[1010]; 9 LL len; 10 LL b, c, s, nb, nc, ns, pb, pc, ps; 11 LL money; 12 13 bool

POJ 3080 Blue Jeans(后缀数组+二分答案)

[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通过拼接符拼成一个串,做一遍后缀数组,二分答案,对于二分所得值,将h数组大于这个值的相邻元素分为一组,判断组内元素是否覆盖全字典,是则答案成立,对于答案扫描sa,输出第一个扫描到的子串即可. [代码] #include <cstdio> #include <cstring> #inclu

【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】

[题目大意] 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. [字符串hash的小笔记] hash[i]=(hash[i-1]*p+idx(s[i]))%mod,idx为映射值,一般a..z映射1..26: 习惯上,p取一个6到8位的素数即可,mod一般取大素数 1e9+7(1000000007)或1e9+9(1000000009). hash[i]=(hash[i-1]*p+idx(s[i]))%mod 表示第 i 个前缀的hash值,是一个hash的前缀和,那么,要求S[l…r]

IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) 二分答案 + 网络流

这道题的意思是给你一个有向图, 每条边上有一个最大载重量, 现在有x头牛要从顶点1走向顶点n, 每头牛要载的重量都是一样的, 问你最多能载多少的重量? 可以二分答案, 算出每头牛的载重, 然后修改边权, 跑一次最大流即可判断当前答案是否正确, 二分答案即可, 注意由于原始边权/每头牛的载重量可能会很大, 因此我们在修改边权时应该注意这一点,将边权的最大值控制在1000000之内, 防止溢出, 代码如下: #include <bits/stdc++.h> using namespace std;