From eff7a86c20a28e713c745fedf62f201b7634f468 Mon Sep 17 00:00:00 2001 From: songyc macbook Date: Mon, 5 Jan 2026 22:59:00 +0900 Subject: [PATCH] logseq 20260105_2 --- pages/분할정복(Divide and Conquer).md | 93 +++++++++++++++++++++++++++ pages/알고리즘.md | 4 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 pages/분할정복(Divide and Conquer).md diff --git a/pages/분할정복(Divide and Conquer).md b/pages/분할정복(Divide and Conquer).md new file mode 100644 index 0000000..831dd5c --- /dev/null +++ b/pages/분할정복(Divide and Conquer).md @@ -0,0 +1,93 @@ +deck:: Logseq/coding tip + +- ## 1. 개념(Concept) + - 크고 복잡한 문제를 {{c1 작고 간단한 하위 문제(Sub-problem)}}들로 나눈 뒤, 각각 해결하여 합치는 알고리즘 설계 패러다임. + id:: 695bbd99-6b9b-4019-a174-9238a89758de +- +- ## 2. 동작 원리 (Algorithm Flow) + - ### 1단계 {{c1 분할(Divide)}} -> 2단계 {{c1 정복(Conquer)}} -> 3단계 {{c1 결합(Combine)}} + id:: 695bbe3e-8b85-4abf-a9ed-6f0c24c8f2dd + #+BEGIN_EXTRA + 분할 : 원래 문제를 같은 유형의 더 작은 하위 문제로 쪼갠다. + 정복 : 하위 문제를 재귀적으로 해결한다.(문제가 충분히 작다면 바로 해결) + 결합 : 하위 문제의 해답들을 합쳐 원래 문제의 답을 만든다. + #+END_EXTRA +- +- ## 3. 시간복잡도 + - ### 문제의 크기를 $N$ 이라고 할 때 {{c1 $O(\log N)$}} 이나 {{c1 $O(N \log N)$}} 으로 감소됨. + id:: 695bbeb8-ecdc-4d0b-a29b-43231188ba86 +- +- ## 4. 예시 + - ### 1) 행렬의 거듭제곱($N \times N$ 크기의 행렬 $A$를 $B$번 거듭제곱 하기) + - #### 점화식 + - $n$이 짝수일 때: $A^n = (A^{n/2}) \times (A^{n/2})$ + - $n$이 홀수일 때: $A^n = (A^{n/2}) \times (A^{n/2}) \times A$ + - #### 행렬곱(multiply_matrix) 함수 코드(python) + id:: 695bc027-6274-498e-b798-0e94060eb147 + $N \times N$ 크기의 행렬 m1, m2와 N을 입력받아서 두 행렬을 곱한 행렬을 반환하는 코드 + #card + - ```python + def multiply_matrix(m1, m2, N): + result = [[0]* N for _ in range(N)] + for i in range(N): + for j in range(N): + for k in range(N): + result[i][j] += m1[i][k] * m2[k][j] + result[i][j] %= 1000 # 문제 조건에 따라 모듈러 연산 추가 + return result + ``` + - #### 분할정복(power_matrix) 함수 코드(python) + 거듭제곱 될 행렬 adj, 현재 곱해지는 지수 n, 행렬의 크기 N을 입력받아서 분할정복으로 adj^n 을 구하는 코드 + - 1) n이 1일 경우(차수가 1일 경우) #card + id:: 695bc161-b88a-4f55-aaf7-7bc17ccd4dcc + - ```python + # Base case : 지수가 1이면 그대로 반환한다. + if n==1 : + return [[num % 1000 for num in row] for row in adj] + ``` + - 2) 분할 #card + id:: 695bc1d6-8a7c-475c-9c51-45a672597058 + - ```python + # Divide: 지수를 절반으로 나누어 재귀 호출 + temp = power_matrix(adj, n//2, N) + ``` + - 3) 정복 및 결합 #card + id:: 695bc232-7ee9-4c02-a3b1-1f65061737f9 + - ```python + if n % 2 == 0: + # 짝수면: temp * temp + return multiply_matrix(temp, temp, N) + else: + # 홀수면: temp * temp * A + return multiply_matrix(multiply_matrix(temp, temp, N), adj, N) + ``` + - 전체코드 + - ```python + # 행렬 곱셈 함수 (N*N 행렬 두 개를 곱함) + def multiply_matrix(m1, m2, N): + result = [ * N for _ in range(N)] + for i in range(N): + for j in range(N): + for k in range(N): + result[i][j] += m1[i][k] * m2[k][j] + result[i][j] %= 1000 # 문제 조건에 따라 모듈러 연산 추가 + return result + + # 분할 정복을 이용한 거듭제곱 함수 + def power_matrix(adj, n, N): + # Base Case: 지수가 1이면 그대로 반환 + if n == 1: + return [[elem % 1000 for elem in row] for row in adj] + + # Divide: 지수를 절반으로 나누어 재귀 호출 + temp = power_matrix(adj, n // 2, N) + + # Conquer & Combine + if n % 2 == 0: + # 짝수면: temp * temp + return multiply_matrix(temp, temp, N) + else: + # 홀수면: temp * temp * A + return multiply_matrix(multiply_matrix(temp, temp, N), adj, N) + + ``` \ No newline at end of file diff --git a/pages/알고리즘.md b/pages/알고리즘.md index ca99a97..2f210be 100644 --- a/pages/알고리즘.md +++ b/pages/알고리즘.md @@ -3,4 +3,6 @@ - [[크루스칼 알고리즘(Kruskal’s Algorithm)]] - [[프림 알고리즘 (Prim’s Algorithm)]] - [[다익스트라 알고리즘 (Dijkstra Algorithm)]] -- [[벨만-포드 알고리즘 (Bellman-Ford Algorithm)]] \ No newline at end of file +- [[벨만-포드 알고리즘 (Bellman-Ford Algorithm)]] +- [[분할정복(Divide and Conquer)]] +- \ No newline at end of file