P3853 [TJOI2007]路标设置

P3853 [TJOI2007]路标设置

​ 这是一个关于区间的二分问题。为什么?因为二分区间可以做这个。大家学学吧。 区间二分,把一个大区间分为不同的小区间,然后吧小区间分段,段数就是二分的比较条件。

一、思路

​ 对于二分,作者认为就是在有序序列的高效的枚举。对于这题我们求得是最小“空旷指数”值。与之挂钩得直接影响结果得变量是路标数量。那么我们能否枚举空旷指数(与之挂钩得路标得数量)来解决这个问题呢?答案是可以得。一旦路标得数量确定放下后间距也就确定了。

二、代码讲解

#include
using namespace std;
const int maxl = 1e7 + 7;

int L, n, k;//公路的长度,原有路标的数量,以及最多可增设的路标数量。
int a[maxl];//两个路标得间距,也即区间间距
int l = 1, r = 0, mid;//l最小为1,因为两个路标之间不可能重合
int before = 0, now;//用来找区间长度

int main(){
    cin >> L >> n >> k;
    for (int i = 0; i < n; i++){
        cin >> now;
        a[i] = now - before;
        before = now;//把 用的过的now设为before 
        r = max(r, a[i]);//寻找最长得区间
    }
    
    a[n] = L - before;//最后一个区间路得末尾到最后一个路障得距离
    r = max(r, a[n]);

    if (k == 0){
		cout << r << endl;
		return 0;
	}
    while (l <= r){//“两闭加等于”看不懂得去翻我的主页二分讲解
        mid = l + ((r - l) >> 1);
		int count = 0;//路障个数
        for (int i = 0; i <= n; i++){//清算以mid(空旷指数)这一段路中的路障个数
            int temp = a[i];
            while (temp > mid){
                count++;
                temp -= mid;
            }
        }
        if (count <= k)	r = mid - 1;//“是闭就添1”
        else	l = mid + 1;
    }
    cout << l << endl;
    return 0;
}

三、最后

​ 给个三连吧!!!创作实属不易。

你可能感兴趣的:(算法,c++,开发语言)