您的位置:首页 > 其它

codeforces 792E —— Colored Balls (贪心,不定方程,数学)

2017-03-29 22:46 495 查看
E. Colored Balls

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

There are n boxes with colored balls on the table. Colors are numbered from 1 to n. i-th
box contains ai balls,
all of which have color i. You have to write a program that will divide all balls into sets such that:

each ball belongs to exactly one of the sets, 

there are no empty sets, 

there is no set containing two (or more) balls of different colors (each set contains only balls of one color), 

there are no two sets such that the difference between their sizes is greater than 1. 

Print the minimum possible number of sets.

Input

The first line contains one integer number n (1 ≤ n ≤ 500).

The second line contains n integer numbers a1, a2, ...
, an (1 ≤ ai ≤ 109).

Output

Print one integer number — the minimum possible number of sets.

Examples

input
3
4 7 8


output
5


input
2
2 7


output
4


Note

In the first example the balls can be divided into sets like that: one set with 4 balls of the first color, two sets with 3 and 4 balls,
respectively, of the second color, and two sets with 4 balls of the third color.

讲道理这道题现在还是不知道正解是啥。。。

看到了一份能看懂的代码,先贴上来。再说我自己的想法。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;

const int MAXN = 500 +10;
const long long INF=0x7fffffffffffffff;
long long ans=INF;
long long a[MAXN];
int n;

void solve(long long x){
long long s=0;
if(x==0)
return;
for(int i=0;i<n;i++){
long long p=a[i]/x;
long long q=a[i]%x;
if(p==0)
return;
if(p>=q){
s+=(a[i]+x)/(x+1);
}else
return;
}
ans=min(ans,s);
}

int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%I64d",a+i);
}
sort(a,a+n);
for(int i=1;i*i<=a[0];i++){
solve(a[0]/i);
solve(a[0]/i+1);
solve(i);
solve(a[0]/i-1);
}
printf("%I64d\n",ans);
}


其实就是暴力,因为每一份的个数肯定不能超过最小的数,所以针对最小的数枚举一下。不过在这个代码里面那个a[i]+x/(x+1)不太懂

我是用不定方程做的。

对于ax+by=n,x=x'-bt,y=y'+at.x',y'为一组特解。

对于p=a[I]/x,q=a[I]%x.

只要p>=q,就能把q分成q个1加到其他集合里面。(p-q)*x+q*(x+1)=a[i],总个数就是p+t,求出t的范围即可。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;

const int MAXN = 500 +10;
const long long INF=0x7fffffffffffffff;
long long ans=INF;
long long a[MAXN];
int n;

void solve(long long x){
long long s=0;
if(x==0)
return;
for(int i=0;i<n;i++){
long long p=a[i]/x;
long long q=a[i]%x;
if(p<q){
return;
}
long long X=(a[i]-q)/x;
long long Y=(p-q)/(x+1);
long long temp=min(X,Y);
s+=p-temp;
}
ans=min(ans,s);
}

int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%I64d",a+i);
}
sort(a,a+n);
for(int i=1;i*i<=a[0];i++){
solve(a[0]/i);
solve(a[0]/i+1);
solve(i);
solve(a[0]/i-1);
}
printf("%I64d\n",ans);
}


然而居然被卡常乐。。

气哭
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: