본문 바로가기

알고리즘/이론

03. 동적계획법 - 예제3

[1. 문제 설명]

수열을 s 가지의 자연수만을 이용하여 양자화 하였을 때,

각 숫자별 오차 제곱의 합을 최소 값을 출력한다.

 

양자화 => 더 넓은 범위를 갖는 값들을 작은 범위를 갖는 값들로 근사해 표현

[161, 164, 178, 184] => 160, 170, 180 으로 표현..

 

 

 

[2. 풀이 접근]

A. 잘못된 접근

주어진 수열 A 이 첫번째 수자를 어떤 숫자로 표현할 것인지 결정하고

나머지 수열에 대해 재귀 호출하는 방식

=> 양자화에 사용 할 숫자에 제한이 있어서, 현재 까지의 결정이 앞으로의 결정에 영향을 준다

=> 최적 부분 조건이 성립하지 않는다.

=> 메모이제이션에 필요한 메모리 확보도 어려울 것.

==> 입력 상, 1000 이하의 숫자 중 10 개의 숫자를 선택하는 경우를 고려해보면...

 

 

B. 올바른 접근

B.1 답의 형태 제한하기

부분 문제의 개수가 너무 많을 때, 시도 할 수 있는 방법

답이 항상 어떤 구조를 가질 것이라고 예측하고, 그것을 강제한다.

 

=> 어떤 숫자 a 와 b 에 대해서 a < b 인 경우

=> a 를 a` 로 양자화 할 때, a` 는 b에 대응되는 값 보다 커서는 안된다.

==> ex) a=10, b=25 이고, b 에 양자값을 20 으로 할 때,

       a 의 양자값이 20보다 커지면, 20 미만일 때 보다 그 오차가 더 커진다.

 

주어진 수열을 오름차순으로 정렬하면,

같은 숫자로 양자화 되는 숫자들은 항상 인접해 있다.

 

따라서, 수열을 정렬하고, 인접한 숫자끼리 묶음으로 적절히 분할하고, 각 묶음을 한 숫자로 양자화 하여,

오차 제곱의 합을 최소화 하는지 확인하도록 한다.

 

즉, 주어진 수열을 s 개의 묶음으로 나누어야 한다.

매 재귀 호출 때마다, 첫 묶음의 크기가 얼마인지 결정하면 된다.

ex) 첫 묶음의 크기가 x 이면, n-x 개의 숫자를 s-1 개의 묶음으로 나누면 된다.

 

이제 최적 부분 구조가 성립하게 된다.

(부분의 오류가 최소이어야, 전체의 오류가 최소가 되기 때문이다.)

(남은 숫자들을 최적으로 묶는데, 이전 조각의 정보는 필요가 없다.)

 

 

B.2 한 구간에 대한 답 찾기

한 구간의 최소 오차 제곱 합을 찾는 가장 쉬운 방법은

주어진 구간의 최소값에서 최대값까지 값 중 하나로 양자화 하여 일일히 계산해보는 것이다.

=> 숫자의 범위가 1000 이하이므로, 시간 내 가능 할 것?

 

그러나, 미분을 이용하여 오차 제곱 합을 최소로 하는 양자 값을 추정 할 수 이다.

이 값을 미지수로 설정하고, 오차 제곱 합 수식의 최소 값을 찾으면 된다.

 

식을 계산하면, 전체 값들의 평균 일 때, 최소가 되는 것을 알 수 있다.

 

한 구간의 범위는 다양 할 수 있으므로, 부분 합을 이용하여 평균을 계산하면,

O(n) 이 아니라 O(1) 의 복잡도로 계산 할 수 있다.

 

 

[3. 코드]

 

 

'알고리즘 > 이론' 카테고리의 다른 글

04. 탐욕법  (0) 2022.10.03
03. 동적계획법 - 예제4  (0) 2022.10.02
03. 동적 계획법 - 예제1  (0) 2022.09.23
03. 동적 계획법  (0) 2022.09.23
02. 분할 정복 예제 - 2  (0) 2022.09.23