Quantization
https://www.algospot.com/judge/problem/read/QUANTIZE
๋์ ๋ต
์๊ณ ๋ฆฌ์ฆ
- ์์ด์ ์ ๋ ฌํ๋ค.
- ๋ถ๋ถ ์์ด๋ค์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋๋ฉด์ ๋ถ๋ถ ์์ด์ ์ค์ฐจํฉ์ด ๊ฐ์ฅ ์ ์ ์์ด์ ๊ตฌํ๋ค.
2๋ฒ ๊ณผ์ ์ ๋ํด์ ์ต์ ๋ถ๋ถ๊ตฌ์กฐ์์ ๋ฐ๊ฒฌํ๊ณ ๊ฐ ๋ถ๋ถ ์์ด์ ์ค์ฐจํฉ์ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ๋ฐฉ์์ผ๋ก ์งํํ์ฌ์ผํ๋ค. ํ์ง๋ง ๋ณธ์ธ์ ๋ฉ๋ชจ์ด์ ์ด์ ์ ๋ถ๋ถ ์์ด์ ๋ชจ๋ ์์ฑํ์ ๋ ์งํํ๋ ์์ผ๋ก ํ์ฌ ์ด์จ๋ ๋ถ๋ถ ์์ด์ ๋ง๋๋ ์ฌ๊ทํจ์์ ๋์ ๋๋ฌํด์ผ ๋ฉ๋ชจ์ด์ ์ด์ ์ ์ธ ์ ์๊ฒ ๊ตฌํํ์๋ค. ์ด ์ ์ด ์๊ฐ์ด๊ณผ์ ์์ธ์ด ๋์๋ค๊ณ ์๊ฐํ๋ค.
์ฝ๋
์ฝ๋1
#include <iostream>
#include <algorithm>
using namespace std;
int N, S;
int arr[100];
int* num_idx; // index 0์ -1, 1 ~ S๊น์ง ์์
int min_res = 1e9;
int memorize[101][101];
void Quantization(int n) { // ๋๋ ํ์
if (n == S - 1) {
int start = 0; int end;
int res = 0;
for (int i = 1; i < S; i++) {
end = num_idx[i];
if (memorize[start][end] != -1) {
res += memorize[start][end];
start = end + 1;
continue;
}
int mid = 0;
for (int j = start; j <= end; j++) {
mid += arr[j];
}
mid /= (end - start + 1);
int mid_arr[3] = { mid - 1,mid,mid + 1 };
int tmp;
int min_mid = 1e9;
for (int j = 0; j < 3; j++) {
tmp = 0;
for (int k = start; k <= end; k++) {
tmp += (int)pow(mid_arr[j] - arr[k], 2);
}
min_mid = min(tmp, min_mid);
}
res += min_mid;
memorize[start][end] = min_mid;
start = end + 1;
}
end = N - 1;
if (memorize[start][end] != -1) {
res += memorize[start][end];
}
else {
int mid = 0;
for (int i = start; i <= end; i++) {
mid += arr[i];
}
mid /= (end - start + 1);
int mid_arr[3] = { mid - 1,mid,mid + 1 };
int tmp;
int min_mid = 1e9;
for (int i = 0; i < 3; i++) {
tmp = 0;
for (int j = start; j <= end; j++) {
tmp += (int)pow(mid_arr[i] - arr[j], 2);
}
min_mid = min(tmp, min_mid);
}
memorize[start][end] = min_mid;
res += min_mid;
}
if (res < min_res)
min_res = res;
return;
}
for (int i = num_idx[n] + 1; i < N - (S - n - 1); i++) {
num_idx[n + 1] = i;
Quantization(n + 1);
}
}
int main() {
int C;
cin >> C;
int ans[50];
int index = 0;
while (C--) {
cin >> N >> S;
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
fill(&memorize[0][0], &memorize[100][101], -1);
sort(&arr[0], &arr[N]);
min_res = 1e9;
num_idx = (int*)malloc(sizeof(int)*(S));
num_idx[0] = -1;
Quantization(0);
ans[index++] = min_res;
delete num_idx;
}
for (int i = 0; i < index; i++)
cout << ans[i] << endl;
}
์๊ฐ ์ด๊ณผ
์ฝ๋2
#include <iostream>
#include <algorithm>
using namespace std;
int N, S;
int arr[100];
int* num_idx; // index 0์ -1, 1 ~ S๊น์ง ์์
int min_res = 1e9;
int memorize[101][101];
int pSum[101], pSqSum[101];
void precalc() {
pSum[0] = arr[0];
pSqSum[0] = arr[0] * arr[0];
for (int i = 1; i < N; ++i) {
pSum[i] = pSum[i - 1] + arr[i];
pSqSum[i] = pSqSum[i - 1] + arr[i] * arr[i];
}
}
void Quantization(int n) { // ๋๋ ํ์
if (n == S - 1) {
int start = 0; int end;
int res = 0;
for (int i = 1; i < S+1; i++) {
end = num_idx[i];
if (i == S)
end = N - 1;
if (memorize[start][end] != -1) {
res += memorize[start][end];
start = end + 1;
continue;
}
int sum = pSum[end] - (start == 0 ? 0 : pSum[start - 1]);
int sqSum = pSqSum[end] - (start == 0 ? 0 : pSqSum[start - 1]);
int m = int(0.5 + (double)sum / (end - start + 1));
int tmp_res = sqSum - 2 * m*sum + m * m*(end - start + 1);
memorize[start][end] = tmp_res;
res += tmp_res;
start = end + 1;
}
if (res < min_res)
min_res = res;
return;
}
for (int i = num_idx[n] + 1; i < N - (S - n - 1); i++) {
num_idx[n + 1] = i;
Quantization(n + 1);
}
}
int main() {
int C;
cin >> C;
int ans[50];
int index = 0;
while (C--) {
cin >> N >> S;
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
if (S >= N) {
ans[index++] = min_res;
}
else {
fill(&memorize[0][0], &memorize[100][101], -1);
sort(&arr[0], &arr[N]);
min_res = 1e9;
num_idx = (int*)malloc(sizeof(int)*(S));
num_idx[0] = -1;
precalc();
Quantization(0);
ans[index++] = min_res;
delete num_idx;
}
}
for (int i = 0; i < index; i++)
cout << ans[i] << endl;
}
index๋ฅผ ์ฌ์ฉํ๊ณ , ์ฌ์ฉํ part ์๋ฅผ ๊ธฐ๋กํด์ ๋ฉ๋ชจ์ด์ ์ด์ ํ๊ธฐ๊ฐ ์ด๋ ค์ ๋ค.
์ฝ๋ 1๊ณผ ์ฝ๋ 2์ ์ฐจ์ด๋ ์ค์ฐจ ์ ๊ณฑ์ ํฉ์ ๊ตฌํ๋ ์๊ฐ์ ์ค์ฌ์ค ๊ฒ๋ฟ์ด๋ค. ์ด๋ ์๊ฐ ์ด๊ณผ๋ฅผ ํด๊ฒฐํด์ฃผ์ง ๋ชปํ๋๋ฐ, ๊ทธ ์ด์ ๋ ํด๋น ์ฝ๋์์๋ memoization์ ํํธ๋ก ๋ค ์ชผ๊ฐฐ์ ๋ (๋ชจ๋ ๋ถ๋ถ ์์ด์ด ๋์์ ๋) ์ ์ฉ ์ํฌ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ค ๊ฒฝ์ฐ์๊ฑด ๋ชจ๋ ๋ถ๋ถ ์์ด์ ๊ตฌํ๊ธดํด์ผํ๋ค. ์ฆ, ์ฌ๊ท์ ๊ธฐ์ ์ฌ๋ก๊น์ง ๋ฐ๋์ ๊ฐ์ผํ๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ๊ตฌํํ์์ผ๋ ์ฌ๊ท์ ํธ์ถ ์๊ฐ ์ค์ง ์์ ์๊ฐ ์ด๊ณผ๊ฐ ๋์ฌ ์ ๋ฐ์ ์๋ค.
๋ณธ์ธ์ด ๋์น ๋ถ๋ถ์ ํด๋น ๋ฌธ์ ๊ฐ ์ต์ ๋ถ๋ถ๊ตฌ์กฐ์ด๋ฉฐ ์ด๋ฅผ ์ด์ฉํด์ ์ฌ๊ทํจ์๋ฅผ ๊ตฌํํ๋ฉด ํ์ฌ ์์น์์ ๋จ์ ํํธ ์๋ฅผ ๊ฐ์ง๊ณ ๊ฐ์ด ์ ์ฅ๋์ด์๋ค๋ฉด ์ฌ๊ท๋ฅผ ๋์ด์ ๋ถ๋ฅด์ง ์์๋ ๋๊ฒ๋ ์คํ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด๋ค.
์ ๋ต์ฝ๋
#include <iostream>
#include <algorithm>
using namespace std;
int N, S;
int arr[100];
int memo[101][11];
int pSum[101], pSqSum[101];
// pSum : idx๊น์ง์ ์์ ํฉ // pSqSum : idx๊น์ง์ ์์^2์ ํฉ
void precalc() { // pSum, pSqSum ๊ตฌํ๊ธฐ
pSum[0] = arr[0];
pSqSum[0] = arr[0] * arr[0];
for (int i = 1; i < N; ++i) {
pSum[i] = pSum[i - 1] + arr[i];
pSqSum[i] = pSqSum[i - 1] + arr[i] * arr[i];
}
}
int minError(int lo, int hi) {
int sum = pSum[hi] - (lo == 0 ? 0 : pSum[lo - 1]);
int sqSum = pSqSum[hi] - (lo == 0 ? 0 : pSqSum[lo - 1]);
int m = int(0.5 + (double)sum / (hi - lo + 1)); // ํ๊ท ๋ฐ์ฌ๋ฆผํด์ ๊ณ์ฐ
int ret = sqSum - 2 * m*sum + m * m*(hi - lo + 1); // ๊ณต์์ ๋์
return ret;
}
int Quantization(int from, int parts) {
if (from == N) return 0; // ๋ชจ๋ ์๋ฅผ ์์ํํ์ ๋ => S๊ฐ N๋ณด๋ค ํด ๋
if (parts == 0) return 1e9; // ๋ชจ๋ ๋ฌถ์์ ๋ค ์ผ์ ๋ => ์์ฃผ ํฐ ์ return
int& ret = memo[from][parts];
// from๋ถํฐ์ ์์๋ฅผ parts๊ฐ์ ๋ฌถ์์ผ๋ก ๋ฌถ๋ ์ต์์ ์ค์ฐจํฉ์ ์ ์ฅ
if (ret != -1) return ret;
ret = 1e9;
for (int partSize = 1; from + partSize <= N; partSize++) {
// ๊ฐ ๋ฌถ์๋ง๋ค 1๊ฐ๋ถํฐ N-ํ์ฌidx ๊ฐ๊น์ง ์์๋ฅผ ๊ฐ์ง๋ฉด์
ret = min(ret, minError(from, from + partSize - 1) + Quantization(from + partSize, parts - 1));
// ๋ค์ ๋ฌถ์๋ค์ ์ค์ฐจ + ํ์ฌ ์ค์ฐจ ๊ณ์ฐ
}
return ret;
}
int main() {
int C;
cin >> C;
int ans[50];
int index = 0;
while (C--) {
cin >> N >> S;
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
fill(&memo[0][0], &memo[100][11], -1);
sort(&arr[0], &arr[N]);
precalc();
ans[index++] = Quantization(0,S);
}
for (int i = 0; i < index; i++)
cout << ans[i] << endl;
}
์ ๋ต ์ฝ๋๋ from์์ parts๊ฐ์ ๋ถ๋ถ ์์ด์ ๋ง๋ค์ด๋ด๋ ์ต์ ๋ถ๋ถํฉ์ ๋ฉ๋ชจ์ด์ ์ด์ ํ๋ ํํ๋ก ์ฝ๋๋ฅผ ๊ตฌํํ์๋ค. ๋ํ ์ค์ฐจ์ ๊ณฑ์ ํฉ์ ๋งค๋ฒ ๊ณ์ฐํด๋ ์๊ฐ์ด๊ณผ๋ ๋์ง ์์ง๋ง ์ ๋ ฅ๋ฒ์๊ฐ ์ต๋ 100๊ฐ์ ์๋ฐ์ ๋์ง ์์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์ ์ฅํด๋๋ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํตํด์ O(1)์ ์๊ฐ๋ณต์ก๋๋ก ์ค์ฐจํฉ์ ๊ณ์ฐํ ์ ์๊ฒ ํ์๋ค.
pSqSum๊ณผ pSum์ ๋ฏธ๋ฆฌ ๋ค ๊ตฌํด๋๋ ๋ฐฉ์์ ์ฌ์ฉ!
+) ๋ฐ์ฌ๋ฆผ์ ๋ค์๊ณผ ๊ฐ์ด ํํํ์๋ค.
๋ฐ์ฌ๋ฆผ ์ = (int)(0.5 + ๊ธฐ์กด ์);
// ํด๋น ์์ 0.5๋ฅผ ๋ํ ํ ๋ด๋ฆผํ๋ ๋ฐฉ๋ฒ
์๊ฐ๋ณต์ก๋
์ต์ ์ ๊ฒฝ์ฐ ์๊ฐ๋ณต์ก๋๋ฅผ ์๊ฐํด๋ณด์.
์ฐ์ ํ ์คํธ์ผ์ด์ค๊ฐ 50๊ฐ์ด๋ฏ๋ก 50 * (Quantization ํจ์์ ์๊ฐ๋ณต์ก๋) ๊ฐ ์ด ์๊ฐ๋ณต์ก๋์ด๋ค. fill์ด๋ sort, precalc ํจ์๋ Qunatization ํจ์๋ณด๋ค ๋ณต์ก๋๊ฐ ๋ฎ์ผ๋ฏ๋ก ์๋ตํ์๋ค.
Quantization ํจ์๋ ์ฌ๊ท์ ์ผ๋ก S๊ฐ 10์ผ ๋ 10๋จ๊ณ๊น์ง ๋ค์ด๊ฐ ์ ์์ผ๋ฉฐ, N๊ฐ์ ์๋ฅผ S๋ฌถ์์ผ๋ก ๋ถํ ํ๋ ๊ฒฝ์ฐ์ ์๊ฐ (n-1)Cs ์ด๋ฏ๋ก ์ต๋ 99C9๋ก ๋ํ๋ผ ์ ์๋ค.
N๊ฐ์ ์ ์ฌ์ด์ ๊ฐ๊ฒฉ์ด N-1๊ฐ์ด๋ฏ๋ก, ์ด ์ค S-1๊ฐ๋ฅผ ์ ํํ๋ฉด N๊ฐ์ ์๋ฅผ S๊ฐ์ set์ผ๋ก ๋๋ ์ ์๋ค.
if๋ฌธ์ผ๋ก ํจ์ ์ด๋ฐ์ return ๋๋ ๊ฒ๋ค์ minError ๊ณ์ฐ์ ๊ฑฐ์น์ง ์์ผ๋ฏ๋ก ์๋ตํด์ฃผ์๋ค.
minError๋ ๋งค๋ฒ ๊ณ์ฐ ์์๋ ์๊ฐ๋ณต์ก๋๊ฐ ๋ง์ด ๋ค๊ฒ ์ง๋ง, ํด๋น ๋ฐฉ๋ฒ์์ ๋ฏธ๋ฆฌ ๊ณ์ฐ์ ํด๋์๊ธฐ ๋๋ฌธ์ O(1)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค.
99C9๋ 2*10^12 ์ ๋์ด๋ฏ๋ก memorization์ ์ฐ์ง ์์์ ๋์ ์๊ฐ๋ณต์ก๋๋ ์ต๋ 50(ํ ์คํธ์ผ์ด์ค)*(2*10^12)(๊ฐ๋ฅํ ๋ฌถ์ ๊ฒฝ์ฐ์ ์)*1(minError๋ณต์ก๋) = 10^14 ์ด๋ฏ๋ก ์๊ฐ ๋ด์ ์คํํ ์ ์๋ค.
=> brute force ์๊ฐ ๋ณต์ก๋ : 10^14
ํ์ง๋ง memorization ๊ธฐ๋ฒ์ ์ฌ์ฉํ์๊ธฐ ๋๋ฌธ์ ๊ฐ index๋ณ๋ก S๊ฐ๋ง ์กฐ์ฌํ๋ฉด ๋๋ค. ์ ํํ ์๊ธฐํ๋ฉด ๋ค์์ 10๊ฐ๊น์ง๋ ๊ฐ๋ฅํ S์ ๊ฐฏ์์ ๋ฐ๋ผ์, 10๊ฐ๋ถํฐ๋ S๊ฐ 1~10๊ฐ ๋ชจ๋ ์กฐ์ฌ ๊ฐ๋ฅํ๋ค. ์ฆ, ์๋ ๊ทธ๋ฆผ์ฒ๋ผ ๊ฒฝ์ฐ์ ์๊ฐ ์๊ธธ ์ ์๋ค.
๋ฐ๋ผ์ index(๋ค์์๋ถํฐ) 1~10์ 1์์ 10๊น์ง ๋ํ ๊ฒ์ด๋ฏ๋ก 55 + 11~100์ ๊ณ์ 10๊ฐ์ ๊ฒฝ์ฐ์ ์๊ฐ ์๊ธฐ๋ฏ๋ก 90*10 = 900 ํด์ ์ด ์ฝ 1000๋ฒ์ ์ฐ์ฐ์ด ํ์ํ๋ค. ์ดํ ๊ฒน์น๋ ์ฐ์ฐ๋ค์ ๋ฉ๋ชจ์ด์ ์ด์ ์ผ๋ก ํด๊ฒฐ๊ฐ๋ฅํ๋ค.
=> ์ต์ข ์๊ฐ ๋ณต์ก๋ : 10^3
ํ ์คํธ์ผ์ด์ค
1
9 3
1 2 3 4 6 9 10 12 13
=> 14
1
9 3
1 2 3 4 6 8 9 10 13
=> 15
2
10 3
3 3 3 1 2 3 2 2 2 1
9 3
1 744 755 4 897 902 890 6 777
=> 0 651
5
9 4
78 76 41 5 3 15 9 81 5
2 3
1 2
10 2
1 7 1 7 2 9 2 9 3 10
17 6
12 45 7 9 78 456 521 789 951 123 457 159 145 764 15 63 21
5 2
1 2 3 4 5
=> 33 0 11 4413 6
๊นจ๋ฌ์ ์
-
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ฏธ๋ฆฌ ์ ์ฅํด๋๋ ๋ฐฉ์์ผ๋ก๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
-
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ด ๊ฐ๋ฅํ ๋ฐฉ์์์๋ ์ต์ ๋ถ๋ถ๊ตฌ์กฐ์ ํด๋นํ๋ ์ง ๊ผญ ์ดํด๋ณด์.
=> ํด๋นํ๋ค๋ฉด ์ฝ๋๊ฐ ํจ์ฌ ์ฌ์์ง๋ค.
(๋จ๊ณ ๋ณ๋ก ์๋ผ์ ๋ฉ๋ชจ์ด์ ์ด์ ๊ฐ๋ฅ)
-
๋ฉ๋ชจ์ด์ ์ด์ ์ ๋ฌธ์ ์์ ์ ์ํ๋ฏ์ด ์ฃผ์๋ฅผ ๋ฐ์์์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ๊ฐ์ฅ ์ด์์ ์ด๋ค.
-
๋ฌธ์ ๋ฅผ ๋ง์ฃผํ์ ๋ ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ์๋ฅด๋ ๊ฒ์ด ๊ฐ์ฅ ๋ฉ๋ชจ์ด์ ์ด์ ํ๊ธฐ ์ข๊ณ ๊ฐ๋จํ๊ฒ ํํ ๊ฐ๋ฅํ์ง ์๊ฐํ๊ณ ๊ตฌํํ์.
Comment