0
点赞
收藏
分享

微信扫一扫

ybtoj 最小时间【二分】

书写经典 2022-02-10 阅读 22

在这里插入图片描述
在这里插入图片描述

很明显能想到二分t,然后问题的关键在于,二分了t之后怎么算出在当前t下的最大值,如果直接用sort肯定会爆,这里可以用另一个函数:nth_element,这个函数的用法跟sort差不多,但是多了一个参数,它的作用是在指定的1-n区间内把m位排好序,然后m左边的都比m小(假设是从小到大排序),右边都比m大,但是并不是有序的,也就是如果m是第三位,那第二位可能比第一位小,但是它们都比m位小,所以放在了前面,这个函数的时间复杂度是O(n),这样就能用二分过

#include<bits/stdc++.h>
using namespace std;
long long k[1000086],b[1000086],h[1000086];
bool cmp(long long x,long long y)
{
	return x>y;
}//从大到小排序
int main()
{
	long long n,m,s;//s一定要开longlong
	cin>>n>>m>>s;
	for (int i=1;i<=n;i++)
	{
		cin>>k[i]>>b[i];
	}
	long long l=0,r=1e9;//这里的l要注意不能是1
	long long mid;
	long long sum=0;
	long long ans=0;
	while(l<r)
	{
		mid=(l+r)/2;
		sum=0;
		for (int i=1;i<=n;i++)
		{
			h[i]=k[i]*mid+b[i];
		}
		
		nth_element(h+1,h+m,h+1+n,cmp);
		
		for (int i=1;i<=m;i++)
		{
			if(h[i]<0)continue;
			sum+=h[i];//不断累加
			if(sum>=s)//满足大于s就跳出并记录答案
			{
				ans=mid;
				r=mid;
				goto next;//用goto直接跳出更方便一点
			}
		}
		l=mid+1;//如果sum>=s就不会跳到这里,所以此时sum必然<s
		next: ;//刚刚for的if会跳到这里
	}
	cout<<ans;
	return 0;
}
举报

相关推荐

0 条评论