Codeforces:Colored Balls

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 \neq 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 \neq 0$,则$r$需要满足$x-r \leqslant k$,否则不能以该$x$划分.

 

最后取最小值即可,总复杂度$O(n\sqrt{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 }

 

posted @ 2017-03-30 18:17  barriery  阅读(351)  评论(0编辑  收藏  举报