感觉自己现在的水平太洼了,连二分这种题都要调好久。感觉二分总是写不对啊,我真是太水了。。。
T1路标设置
在n个数之中插入k个数,使得相邻的两个数之间的差值的最大值最小。
像这种最大值最小类型的题目,都是考虑使用二分策略;
但是这道题我在第一次做的时候却想错了,我使用的贪心,我将相邻的两个数之间的差值进行排序,然后每次选出差值最大的一组数,然后从他们中间插入一个数。
这样做的错误性在于 忽略了相邻的差值最大 这个条件。
但是,我学会了使用priority_queue (也就是一个大根堆) 这个STL STL大法好
priority_queue 定义:priority_queue<Type, Container, Functional>
例如:priority_queue <Edge, vector<Edge>, cmp>
其中 vector
是一个容器,必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector。cmp
是自己写的比较函数。
正解
二分枚举所有可能的结果,然后对结果进行检验,并及时调整左右指针。这就是二分的一般做法。
但是,我的二分在写的时候死活过不去了,就先仍在这里吧(大雾
while (l <= r)
{
int mid = (l + r) / 2;
int total = 0; t = 0;
for (int i = 1; i <= n; i ++)
{
if (a[i] - t > mid)
while (a[i] - t > mid) {
t = t + mid;
++ total;
}
else t = a[i];
}
if (total > k) l = mid + 1;
else r = (ans = mid) - 1;
}
正解是这个样子的:
while(le<=re) //二分
{
mid=(le+re)/2;//枚举最小空旷值
biao=0,t=0;
for(int i=1;i<=n;i++)
{
while(weizhi[i]-biao>mid)//标志空旷距离大于
biao+=mid,t++; //在距之前地点mid距离处放一个路标,并把需要增加的路标++
if(biao<weizhi[i]) biao=weizhi[i];
}
if(t>k) le=mid+1;//大于能加路标,空旷还需扩大
else re=mid-1, ans=mid;//可行则将空旷缩小
}