二分法

二分思想

二分的思想可以求有单调性的问题.
题目链接 : https://codeforces.com/contest/1118/problem/D1
看别人的代码看了好久,多亏了hyw才明白是二分和贪心.
用二分是因为有“单调性”,r天可以喝够,比r大的天数更能喝够.
这题贪心是从大到小先喝每一天的第一杯,再喝每一天的第二杯.
妙啊!

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int sum=0;
	int m,n,a[105];
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];
	}
	sort(a+1,a+1+n);//排好序
	if(sum<m)
	{
		printf("-1");
		return 0;
	}
 
	else{
			int l=1,r=n;//r---->days 因为结果是单调的,所以可以利用二分的思想,看mid天可不可以喝够 
			while(l<r)
			{
				int mid=l+(r-l)/2;//or : mid=r+l>>2  +优先级在>>上面 
				int cnt=0,sum=0,num=0;//while中忘记把num清零了...//cnt也没清零!! 
				for(int i=n;i>=1;i--)
				{
					sum+=max(0,a[i]-cnt);//贪心,先把每天没有惩罚的第一杯喝完,喝了mid天再和每天的第二杯 
					num++;
					if(num==mid)//mid天后,开始喝第二杯 
					{
					 	cnt++; 
						num=0;	
					}
				}
				if(sum>=m)r=mid;//r=mid要保留所以是等于mid 
				else l=mid+1;//r=mid不够用,所以mid不用保留了,从mid下一个开始 			
			}
			cout<<r<<endl; 
		}
}

重新看了一下 mid有种未知数的感觉~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值