当前位置: 代码迷 >> 综合 >> 【CodeForces】【数学】【贪心】792E Colored Balls
  详细解决方案

【CodeForces】【数学】【贪心】792E Colored Balls

热度:53   发布时间:2023-11-21 06:39:21.0

CodeForces 792E Colored Balls

题目大意

NNN个数中,每个数分成若干个数的和,要求必须由x,x?1x,x-1x,x?1构成。求出最少分出的集合个数。

分析

设我们最终从AiA_iAi?分出的数的数量为kkk,分出的数为x,x?1x,x-1x,x?1。则我们可以 通过打表 得到:k≤Aik\le \sqrt{A_i}kAi? ?且有x≤Aix\le \sqrt{A_i}xAi? ?,且xxx越大越好。

这告诉我们可以暴力枚举每块的大小。

我们将AAA排序后来搞(因为xxx最大不能够超过A1A_1A1?)。

然后我们暴力枚举kkk(即第一个数分开的个数,不超过A1\sqrt{A_1}A1? ?),然后检验对于每个数是否成立,这时xxx可以等于?A1k?+1\lfloor\frac{A_1}{k}\rfloor+1?kA1???+1或者?A1k?\lfloor\frac{A_1}{k}\rfloor?kA1???

当一个数AiA_iAi?能被x,x?1x,x-1x,x?1分开时,令a=?Aix?,b=Aimodxa = \lfloor\frac{A_i}{x}\rfloor,b=A_i\mod xa=?xAi???,b=Ai?modx,那么我们可以得到,当b=0b=0b=0或者a+b≥x?1a+b\ge x-1a+bx?1AiA_iAi?可以被x,x?1x,x-1x,x?1分开。

就这样检验就可以了。

打表大法好啊!!!

参考代码

#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 LOACLfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifscanf("%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;
}