【CodeForces】【數學】【貪心】792E Colored Balls

CodeForces 792E Colored Balls

題目大意

NN個數中,每個數分成若干個數的和,要求必須由x,x1x,x-1構成。求出最少分出的集合個數。

分析

設我們最終從AiA_i分出的數的數量爲kk,分出的數爲x,x1x,x-1。則我們可以 通過打表 得到:kAik\le \sqrt{A_i}且有xAix\le \sqrt{A_i},且xx越大越好。

這告訴我們可以暴力枚舉每塊的大小。

我們將AA排序後來搞(因爲xx最大不能夠超過A1A_1)。

然後我們暴力枚舉kk(即第一個數分開的個數,不超過A1\sqrt{A_1}),然後檢驗對於每個數是否成立,這時xx可以等於A1k+1\lfloor\frac{A_1}{k}\rfloor+1或者A1k\lfloor\frac{A_1}{k}\rfloor

當一個數AiA_i能被x,x1x,x-1分開時,令a=Aix,b=Aimod  xa = \lfloor\frac{A_i}{x}\rfloor,b=A_i\mod x,那麼我們可以得到,當b=0b=0或者a+bx1a+b\ge x-1AiA_i可以被x,x1x,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 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章