奶牛晒衣服(二分)(贪心)

奶牛晒衣服

题目描述

一件衣服在自然条件下用一秒的时间可以晒干 a点湿度。抠门的熊大妈只买了一台烘衣机 。使用用一秒烘衣机可以让一件衣服额外烘干 b 点湿度(一秒晒干 a+b 湿度),但在同一时间内只能烘一件衣服。现在有 nn 件衣服,第 i衣服的湿度为 wi(保证互不相同),要你求出弄干所有衣服的最少时间(湿度为 0 为干 )。

输入格式

第一行三个整数,分别为 n,a,b。
接下来 2 到 n+1 行,第 i行输入wi​。

输出格式

一行,弄干所有衣服的最少时间。

输入

3 2 1
1
2
3

输出

1

样例解释

让机器烘第三件衣服即可一秒完成。

数据范围
1 ≤ w i , a , b , n ≤ 5 × 1 0 5 1 \le w_i,a,b,n \le 5 \times 10^5 1wi,a,b,n5×105
这个题目用两种思路来解决(二分)和(贪心)

二分思路:

这里是对答案进行二分,我们预测一个答案的范围,取这个范围的中点,试探是否可行。

​ **如果可行,将这个范围的右边的范围缩小到mid-1(注意我们所求是最短时间,所以当mid可行的时候我们是将预测的最大的值变小),这个。。。我昏了好久(不说了都是,说就是废物

**如果不可行,说明我们预测的这个范围左边部分都不可行,将l变为mid+1,将我们的预期时间变大

讲讲判断具体是怎么操作的吧:

ans代表我们预测的天数,遍历每一件衣服,如果在预测的天数里面,衣服没能自己风干.则减去风干的湿度,剩下的我们看使用烘干机需要多少天,如果需要烘干机的天数比我们预测的天数还多?相当于每天使用烘干机还没干说明:阿sir预测的天数不可能完成任务啊,

完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,a,b;//n件衣服,a代表自然风干,b代表烘干机每分钟能烘干的湿度
int s[500010];//存放每件衣服的湿度
int check(int ans)//ans代表此时我们预测的天数
{
	int sum=0;//烘干机所用的天数
	for(int i=1;i<=n;i++)
	{
		if(s[i]>ans*a)//衣服没能自己风干
		{
		sum+=ceil((s[i]-ans*a)*1.0/b);//烘干机所用天数(向上取整)	
	    }
	}
	if(sum>ans) return 0;//此方案不行,回去汇报吧,十天搞不完,宽限些十二天咋样
    return 1;
}
int main()
{
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);
	}
	sort(s+1,s+1+n); //排序的目的是确定最初我们预测的范围
 	int l=1;
	int r=s[n];
	int mid,res=0;//res存放最后答案
	while(l<=r)
	{
		mid=(l+r)>>1; //mid为预测范围的中点
		if(check(mid)) 
		    r=mid-1,res=mid; //mid可行,说明我们可以贪心一点,天数可以更少
		else
		    l=mid+1;//mid不行,我们必须宽限些时间了
	}
	printf("%d\n",res);
	return 0;
}

贪心+优先队列

思路:贪心就很好理解,就是每次烘干最湿的那件衣服,其他的在这一分钟自然风干,干的最快;

然后还记得之前的优先队列嘛,正好每次需要最湿的那件,正好还可以自动排序,一切怎会如此巧合

具体操作我就放代码里面啦~就不赘述了!如果不懂优先队列的,可以看我主页里面还有优先队列入门哦

一切正是如此巧合(脚动滑稽)

这里需要注意的是,我将风干的湿度用sum在队列外表示的,并没有将队列的每一个元素进行减去这个湿度的操作

完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,a,b;

priority_queue<int,vector<int>,less<int> >p;//大顶锥

int main()
{
	int t;
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&t); 
		p.push(t);//每件衣服湿度压入优先队列,
	}
	int sum=0,temp1,temp2;//sum代表天数
    //标准死循环
	while(1)
	{
		temp1=p.top()-sum*a;//temp用于判断在sum天,p.top()最湿的那件衣服是否干了
		if(temp1<=0) break;//最湿的都干了,其他的肯定也干了啊
		
		temp2=temp1+sum*a-b;//还没跳出循环?说明最湿的衣服没干呗,那烘一烘放进去继续排序,只减去别的衣服没有操作的,用烘干机烘干的湿度。
        
		p.pop();//原本的p.top()不存在了,我用烘干机烘干了一部分,他变成了temp2
		p.push(temp2);//将temp2继续放进去排序,烘干,排序
		sum++;
	}
	printf("%d\n",sum);
	return 0;
}

在这里插入图片描述
欢迎大家友好评论,有啥问题dd我呀~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值