(Codeforces802Div2)D. River Locks(贪心+思维)

题目链接:Problem - D - Codeforces

输入样例:

5
4 4 4 4 4
6
1
3
6
5
2
4

输出样例:

-1
-1
4
4
-1
5

题意:给定n个水桶,每个水桶的容量为ai,我们可以选择在一些水桶上面放一个水管,每个水管每秒流下1体积的水,但是一个水桶上面最多放一个水管,如果第i个水桶装满了那么水会自动流向第i+1桶,有T个询问,每次询问给我们一个t,问我们至少需要多少个水管可以在时间t内把所有水桶的水都装满。如果无解就输出-1.

分析:由于一桶水装满之后水会自动流向下一桶,但是下一桶水满后不会自动流向上一桶,所以水管的位置肯定是越靠前越好,那么什么情况对应着无解呢?其实就是存在一个位置i,前i个水桶的容积和大于前i个位置所放置的水管在时间t内的总流量,这个时候就会出现无解,如果无解,那么就算我们在前i个水桶上每个位置放上一个水管也不能使得在时间t内将前i个水桶装满,所以这就等价于我们找一个前缀的最大平均值,而前缀的平均值就对应了我们每一个水桶放一个水管且能够装满水桶所需要的最少时间,由于每个前缀都对应着一个时间,为了使得所有水桶都能够被装满,所以我们应该选取一个最大值,也就是求出前缀的最大平均值当所给时间t小于最大平均值时就无解,那肯定就有当所给时间大于等于前缀的最大平均值时有解,那么解是什么呢?按照我们一开始的贪心思路,应该尽可能地把水管摆在靠前的位置,如果我们能让这些水管在时间t内的总流量大于所有水桶的总容量那么肯定能够满足题意,适当地变形就有我们至少需要的水管数量就是我们在时间t内装满所有水桶所需要的水管数量,那么就是总容量除以时间t的上取整,分析到这代码就很容易实现了

下面是代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
const int N=2e5+10;
long long a[N],n;
int main()
{
	cin>>n;
	long long sum=0;
	double aver=0;//记录一下最大前缀平均值 
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		sum+=a[i];
		aver=max(aver,sum*1.0/i);
	}
	int T;
	cin>>T;
	while(T--)
	{
		long long t;
		scanf("%lld",&t);
		if(t<aver) puts("-1"); 
		else printf("%lld\n",(sum-1)/t+1);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值