CodeForces 792E Colored Balls
題目大意
將個數中,每個數分成若干個數的和,要求必須由構成。求出最少分出的集合個數。
分析
設我們最終從分出的數的數量爲,分出的數爲。則我們可以 通過打表 得到:且有,且越大越好。
這告訴我們可以暴力枚舉每塊的大小。
我們將排序後來搞(因爲最大不能夠超過)。
然後我們暴力枚舉(即第一個數分開的個數,不超過),然後檢驗對於每個數是否成立,這時可以等於或者。
當一個數能被分開時,令,那麼我們可以得到,當或者時可以被分開。
就這樣檢驗就可以了。
打表大法好啊!!!
參考代碼
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int Maxn = 500;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
int N;
int A[Maxn + 5];
void check(int siz) {
ll sum = 0;
for(int i = 1; i <= N; i++) {
int p = A[i] / siz, q = A[i] % siz;
if(q == 0 || p + q >= siz - 1)
sum += p + (q != 0);
else return;
}
printf("%lld\n", sum);
exit(0);
}
int main() {
#ifdef LOACL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
scanf("%d", &N);
for(int i = 1; i <= N; i++)
scanf("%d", &A[i]);
sort(A + 1, A + N + 1);
int ans = INF;
for(int i = 1; i * i <= A[1]; i++) {
check(A[1] / i + 1);
check(A[1] / i);
}
printf("%d\n", ans);
return 0;
}