Hello Ocean! 🌼

[μ•Œκ³ μŠ€νŒŸ] μ–‘μžν™” #Quantize, μ±… 8.9절 λ³Έλ¬Έ

Algorithm

[μ•Œκ³ μŠ€νŒŸ] μ–‘μžν™” #Quantize, μ±… 8.9절

bba_dda 2020. 5. 11. 18:50
λ°˜μ‘ν˜•

문제 

https://www.algospot.com/judge/problem/read/QUANTIZE

 

algospot.com :: QUANTIZE

Quantization 문제 정보 문제 Quantization (μ–‘μžν™”) 과정은, 더 넓은 λ²”μœ„λ₯Ό κ°–λŠ” 값듀을 μž‘μ€ λ²”μœ„λ₯Ό κ°–λŠ” κ°’λ“€λ‘œ 근사해 ν‘œν˜„ν•¨μœΌλ‘œμ¨ 자료λ₯Ό 손싀 μ••μΆ•ν•˜λŠ” 과정을 λ§ν•œλ‹€. 예λ₯Ό λ“€μ–΄ 16λΉ„νŠΈ JPG νŒŒμΌμ„ 4컬러 GIF 파일둜 λ³€ν™˜ν•˜λŠ” 것은 RGB 색 κ³΅κ°„μ˜ 색듀을 4컬러 μ€‘μ˜ ν•˜λ‚˜λ‘œ μ–‘μžν™”ν•˜λŠ” 것이고, ν‚€κ°€ 161, 164, 170, 178 인 학생 넷을 '160λŒ€ λ‘˜, 170λŒ€ λ‘˜' 이라고 μΆ•μ•½ν•΄ ν‘œν˜„ν•˜λŠ” 것 λ˜ν•œ μ–‘μžν™”λΌκ³  ν• 

www.algospot.com

μš”μ•½ν•˜μžλ©΄ 주어진 μˆ˜μ—΄μ„ s개의 숫자둜 μ–‘μžν™” ν•  λ•Œ, 각 μˆ«μžλ³„ 였차제곱의 합을 μ΅œμ†Œν™” ν•˜λŠ” μ–‘μžν™” κ²°κ³Όλ₯Ό ꡬ해야 ν•˜λŠ” λ¬Έμ œμ΄λ‹€. 

 

풀이

책에 μžˆλŠ” 풀이λ₯Ό 많이 μ°Έκ³ ν•˜μ˜€λ‹€. 

λ¨Όμ €, a와 bλΌλŠ” λ‘κ°œμ˜ μˆ«μžκ°€ μžˆμ„ λ•Œ 이 μˆ«μžλ“€μ˜ μ–‘μžν™” κ²°κ³Όλ₯Ό 각각 A,B라고 ν•˜μž. 

a<b일 λ•Œ, A>B이면 μ•ˆλœλ‹€. (였차λ₯Ό μ΅œμ†Œν™” ν•˜λŠ” 것이 λͺ©ν‘œμ΄κΈ° λ•Œλ¬Έμ—)

 

λ”°λΌμ„œ 주어진 μˆ˜μ—΄μ„ κ·ΈλŒ€λ‘œ μ–‘μžν™”ν•˜κΈ° λ³΄λ‹€λŠ” 크기순으둜 μ •λ ¬ν•΄μ„œ μΈμ ‘ν•œ μˆ˜λ“€λΌλ¦¬ 같은 숫자둜 μ–‘μžν™” ν•˜λŠ” 것이 λ°”λžŒμ§ν•˜λ‹€. 

-> μ •λ ¬λœ μˆ˜μ—΄μ„ μˆœμ„œλŒ€λ‘œ s개의 묢음으둜 λΆ„ν• ν•˜λŠ” λ¬Έμ œκ°€ λœλ‹€. 

첫 묢음의 크기가 x라면 κ·Έ λ‹€μŒ λ¬Έμ œλŠ” n-x개의 μˆ«μžλ“€μ„ s-1개의 묢음으둜 λΆ„ν• ν•˜λŠ” λ¬Έμ œκ°€ λœλ‹€. 

 

그리고 μ–΄λ– ν•œ 묢음 pλ₯Ό k둜 μ–‘μžν™” ν•  λ•Œ, κ·Έ κ·Έλ£Ήλ‚΄μ˜ 였차λ₯Ό μ΅œμ†Œν™”ν•  수 μžˆλŠ” kλŠ” p λ‚΄λΆ€μ˜ μˆ«μžλ“€μ˜ 평균값이 λœλ‹€.

(kκ°€ μ •μˆ˜μ—¬μ•Ό ν•˜λ―€λ‘œ p λ‚΄λΆ€μ˜ μˆ«μžλ“€μ˜ 평균값을 λ°˜μ˜¬λ¦Όν•΄μ„œ μ‚¬μš©ν•œλ‹€)

μ±…μ—μ„œλŠ” 이 점을 μˆ˜ν•™κ³΅μ‹μ„ μ΄μš©ν•΄ μ„€λͺ…ν•˜μ˜€μœΌλ‚˜, ν™•λ₯ κ³Ό 톡계λ₯Ό 배운 μ‚¬λžŒμ΄λΌλ©΄ 이 λ¬Έμž₯을 μˆ˜ν•™κ³΅μ‹ 없이도 이해할 수 μžˆμ„ 것이라고 μƒκ°ν•œλ‹€. 

 

p λ‚΄λΆ€μ˜ 평균을 κ΅¬ν•˜λŠ” μž‘μ—…μ€ O(n)의 λ³΅μž‘λ„κ°€ μ†Œμš”λ  수 μžˆμ§€λ§Œ, 

0번째 수 λΆ€ν„° i번째 수 κΉŒμ§€μ˜ 합을 μ €μž₯ν•˜λŠ” pSum[i]λ₯Ό μ΄μš©ν•΄μ„œ O(1)둜 ꡬ할 수 μžˆλ‹€. 

a번째 ~ b번째 숫자의 평균 : ( pSum[b] - pSum[a-1] ) / b-a+1 

* aκ°€ 0μΌλ•ŒλŠ” a-1 인덱슀λ₯Ό μ ‘κ·Όν•  수 μ—†μœΌλ―€λ‘œ λ”°λ‘œ μ²˜λ¦¬ν•΄μ€€λ‹€. 

 

#include <stdio.h>
#include <algorithm>
using namespace std;
//minError()λ₯Ό O(1)으둜 κ³„μ‚°ν•˜κΈ° μœ„ν•΄ μ‚¬μš©
int n, s;
int arr[101];
int psum[101];
int pSqSum[101]; 
const int INF = 987654321; //INT_MAXλ₯Ό μ‚¬μš©ν•˜λ©΄ μ•ˆλœλ‹€. 
int minError(int start,int end) { //start와 end μ‚¬μ΄μ˜ μ΅œμ†Œμ—λŸ¬λ₯Ό return 
	int sum,sqSum;
	if (start == 0) {
		sum = psum[end];
		sqSum = pSqSum[end];
	}
	else {
		sum = psum[end] - psum[start - 1];
		sqSum = pSqSum[end] - pSqSum[start - 1];
	}
	//start와 endμ‚¬μ΄μ˜ μˆ˜λ“€μ„ 평균값을 λ°˜μ˜¬λ¦Όν•œ 수둜 μ–‘μžν™”
	int m = int(0.5 + (double)sum / (end - start + 1));
	//result = sum(arr[i]-m)^2
	int result = sqSum - 2 * m * sum + m * m * (end - start + 1);
	//printf("minError(%d, %d) = %d\n", start, end, result);
	return result;
}
int cache[101][11]; //주어진 μˆ˜μ—΄μ˜ startμœ„μΉ˜λΆ€ν„° 끝 숫자 κΉŒμ§€ parts개의 묢음으둜 λ‚˜νƒ€λ‚΄μ•Ό ν•  λ•Œ κ°€λŠ₯ν•œ κ°€μž₯ μž‘μ€ sqError μ €μž₯ 
int quantize(int start, int parts){
	if (start == n) return 0; //끝에 λ„λ‹¬ν–ˆμ„ λ•Œ 
	if (parts == 0) return INF; //더 이상 묢을 수 없을 λ•Œ, 잘λͺ»λœ κ²½μš°μ΄λ―€λ‘œ μ΅œλŒ“κ°’ λ°˜ν™˜
	int & ret = cache[start][parts]; 
	if (ret != -1) return ret;
	ret = INF;
	printf("ret : %d\n", ret);
	//ν•΄λ‹Ή 묢음의 길이λ₯Ό λ³€ν™”μ‹œν‚€λ©΄μ„œ μ΅œμ†Ÿκ°’ μ°ΎκΈ°
	for (int size = 1;start + size <= n;size++) {
		ret = min(ret, minError(start, start + size - 1) + quantize(start + size, parts - 1));

	}
	return ret;
}
int main() {
	int C;
	scanf_s("%d", &C);
	for (int c = 0;c < C;c++) {
		scanf_s("%d %d", &n, &s);
		for (int i = 0;i < n;i++)
			scanf_s("%d", &arr[i]);
		sort(arr, arr+n);
		psum[0] = arr[0];
		pSqSum[0] = arr[0] * arr[0];
		for (int i = 0;i < n;i++) {
			psum[i] = psum[i - 1] + arr[i];
			pSqSum[i] = pSqSum[i - 1] + arr[i] * arr[i];
		}
		fill(&cache[0][0], &cache[101][11],-1);
		printf("%d\n", quantize(0, s));
	}
} 

minError(int start, int end) 

: start ~ end κΉŒμ§€κ°€ ν•œ 묢음 일 λ•Œ (ν•˜λ‚˜μ˜ 숫자둜 μ–‘μžν™” ν•  λ•Œ) κ°€λŠ₯ν•œ μ΅œμ†Œμ˜ error return  

quantize(int start, int parts)

: start λΆ€ν„°μ˜ μˆ«μžλ“€μ„ parts개의 묢음으둜 뢄리할 λ•Œ κ°€λŠ₯ν•œ μ΅œμ†Œμ˜ error return 

λ°˜μ‘ν˜•