Codeforces:Colored Balls
题目链接:http://codeforces.com/contest/792/problem/E
题目大意:有$n$种颜色,第$i$种颜色有$a_i$个球。现要将这些球放入盒内,要求一个盒子只能放一种颜色,任意两个盒子中球的个数差不大于$1$,问最少需要多少个球。
枚举,贪心
设每个盒子中可以存放$x$或$x+1$个球,则任意颜色的球的个数都可以表示为$ux+v(x+1)$.
故可任选一种颜色的球$a$,枚举$p$,令$k=a/p$,$r=a\%p$,即$a=kp+r$.
根据$r$的值,可分为两种情况:
- $r eq 0$时,$x$仅有两种可能,$x=k$或$x=p$.
- $r = 0$时,$x$有四种可能,$x=k$或$x=p$或$x=k-1$或$x=p-1$.
将上面得到的$x$带入各个颜色检验,由于要求最少盒子,故优先以$x+1$为单位将球分组:$a_i=k(x+1)+r$.
显然,若$r eq 0$,则$r$需要满足$x-r leqslant k$,否则不能以该$x$划分.
最后取最小值即可,总复杂度$O(nsqrt{a_i})$.
代码如下:
1 #include <cstdio > 2 #include <iostream> 3 using namespace std; 4 typedef long long ll; 5 ll inf=1e15; 6 ll n,a[505],ans=inf; 7 ll js(ll x){ 8 ll tmp=0; 9 for(int i=0;i<n;++i){ 10 if(a[i]%(x+1)!=0&&x-a[i]%(x+1)>a[i]/(x+1))return inf; 11 tmp+=a[i]/(x+1)+(a[i]%(x+1)?1:0); 12 }return tmp; 13 } 14 int main(){ 15 std::ios::sync_with_stdio(false); 16 cin>>n; 17 for(ll i=0;i<n;i++)cin>>a[i]; 18 for(ll i=1;i*i<=a[0];++i){ 19 ll k=a[0]/i; 20 ans=min(ans,js(i)); 21 ans=min(ans,js(k)); 22 if(a[0]%i==0){ 23 if(k-1)ans=min(ans,js(k-1)); 24 if(i-1)ans=min(ans,js(i-1)); 25 } 26 }cout<<ans; 27 }