CF 792E Coloured Ballons 平方分割+枚举

题意:n种颜色的气球 第i种颜色气球有a[i]个 现在用盒子来装气球,
条件:不能有空盒子,每个盒子只能装同种颜色的气球,任意两个盒子装的气球个数相差<=1.
问最少需要多少个盒子把所有气球都装起来?  n<=500,a[i]<=1e9.


任意两个盒子气球个数差<=1 假如装的球为x,x-1.
x<=a[i]<=1e9.不能直接枚举x,因为一种颜色分的组数k和每组size 不会同时大于sqrt(a[i]).
a[1]为最小值,x<=a[1]+1,所以直接枚举x=[1,sqrt(a[1])]部分.在通过枚举k=[1.sqrt(a[1])] 则此时x最多为[(a[1]+k-1)/k] (上取整)
最后通过枚举出的x 判定一遍即可 O(N*sqrt(a[1])).

x判定方法: a[i]可以分成a[i]/x组 剩下a[i]%x 若a[i]%x+a[i]/x>=x-1则可行.(前a[i]/x组拿1给最后一组).

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=30;
const ll inf=2e16;
int n,a[N]; 
ll check(ll x)
{
	ll res=0;
	for(int i=1;i<=n;i++)
	{
		ll d=a[i]/x,r=a[i]%x;
		res+=d;
		if(r)
			res++;
		if(r&&d+r<x-1)
			return inf;
	}
	return res;
}
int main()
{
   	cin>>n;
   	for(int i=1;i<=n;i++)
   		cin>>a[i];
   	sort(a+1,a+1+n);
   	ll ans=inf;
	for(ll i=1;i*i<=a[1];i++)
   	{
   		ans=min(ans,check(i));
		ll k=i,x=(a[1]+k-1)/k;
   		ans=min(ans,check(x));
	}
	ans=min(ans,check(a[1]+1));
	cout<<ans<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值