하한 (Lower Bound)

-> 최댓값 계산을 위한 비교횟수 하한 증명

def arrayMax(A):
	m = A[0]
	for i in range(1, len(A)):
		if m < A[i]: // n-1 번 수행
			m = A[i] // 입력값에 따라 다름
	return m
  • 상한 : n - 1

  • 하한: 토너먼트 형식으로 두 개씩 짝지어서 비교

악당과의 게임( adversary argument)

=> 알고리즘이 악당에게 x, y 비교 시키기 & 악당이 대답하면 다음으로 무엇을 비교할 지

  • 값의 상태:
    • N: 한번도 비교되지 않은 상태
    • W: 항상 이긴 상태 (한번도 진 적 없음)
    • L: 최소 한번 이상 진 상태
  • 최종상태:

    => W 1개( 최댓값 )

    => ★ L (n - 1)개

  • 이긴 것은 계속 이길 수 있게 배정

  • 비교를 할 때 L은 최대 1개밖에 안 만들어짐

    => 최소 n - 1번 비교 반드시 필요!! (하한)

분할 정복법

: 큰 문제를 작은 문제로 분할해 재귀적으로 해결

1. 한 개를 나머지 전체와 비교

ex) 최댓값 찾기

max(A) = max(A[0], max[1: ])

  • T(n) = T(n-1) + c, T(1) = c

    => T(n) = O(n)

2. 절반 나누기

ex) 최댓값 찾기

max(A) = max(max(A[ :4]), max(A[4: ]))

  • T(n) = 2 T(n/2) + c, T(1) = c

    => T(n) = O(n)

3. 재귀호출

ex) 제곱

Power1(a,n):
	if n == 1: return a
	return a * power1(a, n-1)
  • T(n) = T(n-1) + c, T(1) = c

    => T(n) = O(n)

Power2(a,n):
	if n == 1: return a
	if n == 0: return 1   			# a^0 = 1
	
	# a^n = a^(n/2) * a^(n/2) 
	
	if n % 2 == 0:		  			# n = 짝수			
    	return Power2(a, n//2) * Power2(a, n//2)
   
    else: return Power2(a, n//2) * Power2(a, n//2) # n = 홀수
	
  • T(n) = 2T(n/2) + c, T(1) =c

    => T(n) = O(n)

Power3(a,n):
	if n == 0: return 1
	x = Power3(a, n//2)  # x = a^(n/2)
	if n % 2 == 0: return x * x
	else return x * x * a	
  • T(n) = 2T(n/2) + c, T(1) = c

​ (n = 2^k 라 가정)

​ = T(n/4) +c + c

​ …=T(n/(2^k)) + kc

​ = k(c+1)

=> T(n) = O(logn)

Fibonacci 수 계산 방법

  • 점화식:

    F0, F1 : 주어짐

    Fn = F(n-1) + F(n-2)

  • 수행시간:

    T(n) = T(n-1) + T(n-2)

  • 방법 1

def fibo1(n) #return Fn
	if n == 0 or n == 1: return n
	return fibo1(n-1) + fibo1(n-2)

=> 중복적으로 호출함!

  • T(n) = T(n-1) + T(n-2)

    =>image

  • 방법2 (행렬)

imageimage

image

교재

  • 리스트 => O(n)
  • 두 변수 => O(n)