(二分、思维)洛谷 P4090 USACO17DEC Greedy Gift Takers P 题解

题意

Farmer John 的死对头 Farmer Nhoj 有 NNN 头奶牛,编号为 1...N1 \dots N1...N。

为此,Farmer John 拿出了他无限的礼物供应,试图给它们送礼物。Nhoj 的奶牛在他面前排成一队,奶牛 111 在队首,奶牛 NNN 在队尾。Farmer John 原本以为,在每一时刻,队首的奶牛会从 Farmer John 那里拿走一份礼物,然后走到队尾。

然而,他刚刚意识到 Nhoj 的奶牛并不那么礼貌!每头奶牛在收到礼物后,可能不会走到队尾,而是可能会插队到队尾的某些奶牛前面。具体来说,奶牛 iii 总是会插队到恰好 cic_ici 头奶牛前面(0≤ci≤N−10 \leq c_i \leq N-10≤ci≤N−1),即排在位置 n−cin-c_in−ci 的奶牛前面。

请帮助 Farmer John 找出无论送出多少礼物,都无法收到任何礼物的奶牛数量。

1≤N≤1051\le N\le 10^51≤N≤105。

思路

这题居然让一众大佬忙得团团转呢......

先找到几个结论:

  • 一头奶牛永远没有礼物,它后面的奶牛也永远都没有;
  • 存在一头奶牛,它前面的奶牛都拿到过礼物,它和它后面的奶牛永远都没有。

于是我们想要找到这个"第一头奶牛"。假如我们会判断一头奶牛能否拿到礼物:

  • 它能拿到礼物,"第一头奶牛"必然在它前面;
  • 它不能拿到礼物,"第一头奶牛"可能是它或者在它的前面。

这具有单调性呢。因此可以二分这个"第一头奶牛"的位置 midmidmid。

根据上面的结论,我们钦定 1∼mid−11\sim mid-11∼mid−1 的奶牛全都拿到礼物,进行了插队操作。设这头被判断的奶牛的实时位置是 temtemtem,一开始 tem=midtem=midtem=mid。

位置原在 midmidmid 的奶牛之所以拿不到,是因为拿礼物的奶牛总是重复的是,原在 1∼mid−11\sim mid-11∼mid−1 的奶牛之中的一部分。即会有"循环"。

这个过程大概就是,1∼mid−11\sim mid-11∼mid−1 的奶牛走到各自的落点 bi=n−aib_i=n-a_ibi=n−ai 后(可能 bib_ibi 存在相同,不过对于"往前顶"只是若干次 −1-1−1 而已),走到了 temtemtem 的后面,把 temtemtem 往前顶了几个位置到 tem′tem'tem′;再拿一轮礼物,又有新的奶牛走到 tem′tem'tem′ 后面,继续被往前顶......直到没法再被往前顶,并且没有被顶到第一个。

又因为每个奶牛的落点是固定的,所以这个过程可以被简化为:按照落点 bib_ibi 从后往前依次插入到后面去,如果 bi≥temb_i\ge tembi≥tem 就 tem--,否则出现 bi<temb_i<tembi<tem 确定这头奶牛永远没法到第一个位置拿礼物了。

(这个好像有点感性呢,但是模拟一下会发现确实如此)

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e5+9;
ll n;
ll a[N],b[N];
bool cmp(ll x,ll y)
{
	return x>y;
}
bool check(ll mid)
{
	for(int i=1;i<mid;i++)
	b[i]=n-a[i];
	sort(b+1,b+mid,cmp);
	ll tem=mid;
	for(int i=1;i<mid;i++)
	{
		if(b[i]<tem)return 1;
		tem--;
	}
	return 0;
}
int main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	ll l=1,r=n,pos=n+1;
	while(l<=r)
	{
		ll mid=(l+r)>>1;
		if(check(mid))pos=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%lld",n-pos+1);
	return 0;
}
相关推荐
.格子衫.5 小时前
022数据结构之树状数组——算法备赛
数据结构·算法·1024程序员节
黑科技Python5 小时前
生活中的“小智慧”——认识算法
学习·算法·生活
sali-tec6 小时前
C# 基于halcon的视觉工作流-章52-生成标定板
开发语言·图像处理·人工智能·算法·计算机视觉
IT古董6 小时前
【第五章:计算机视觉-项目实战之推荐/广告系统】2.粗排算法-(4)粗排算法模型多目标算法(Multi Task Learning)及目标融合
人工智能·算法·1024程序员节
熬了夜的程序员6 小时前
【LeetCode】89. 格雷编码
算法·leetcode·链表·职场和发展·矩阵
對玛祷至昏7 小时前
数据结构理论知识
数据结构·算法·排序算法
oliveira-time7 小时前
二分搜索(Binary Search)
算法
王哈哈^_^7 小时前
【数据集】【YOLO】【目标检测】口罩数据集,口罩佩戴识别数据集 1971 张,YOLO佩戴口罩检测算法实战训练教程。
人工智能·算法·yolo·目标检测·计算机视觉·ai·视觉检测
dragoooon348 小时前
[优选算法专题四.前缀和——NO.31~32 连续数组、矩阵区域和]
数据结构·算法·leetcode·1024程序员节
py有趣8 小时前
LeetCode算法学习之移除元素
java·数据结构·算法