알고리즘으로 생각하기 - 양성봉 참고
백준 문제를 풀다가 알고리즘 풀이가 잘 기억이 나지 않아서
교과서에 있는 알고리즘 코드를 외우기 위해 작성
작은 것부터 풀어보기
설명
문제를 작은 것부터 풀어본다 → 작은 문제들을 먼저 풀어서 그 해를 이용하여 문제 해결
→ 동적 계획
작은 문제: 원래 주어진 문제와 같은 문제, 작은 문제를 부분 문제라고 함
가장 긴 증가 순서
설명
숫자가 일렬로 나열되었을 때 가장 긴 증가 순서를 찾아보자.
증가 순서는 숫자들이 반드시 이웃해야만 할 필요 X
[5, 2, 8, 6, 4, 6, 1, 9, 3]에서 [5, 8, 9], [5, 6, 9], [2, 4, 6, 9] 등 전부 증가 순서
가장 긴 증가 순서는 [2, 4, 6, 9]이다.
문제를 다른 형태의 문제로 바꾸어 생각하기 → 그래프 만들기
각 점에서 오른쪽에 위치한 점에 대해서 자신보다 큰 숫자를 가진 점을 간선으로 연결
가장 긴 증가 순서는 그래프에서 가장 긴 경로에 있는 숫자들과 같다.
알고리즘
[1] 주어진 숫자들을 가지고 그래프를 만듦
[2] 가장 왼쪽 정점으로부터 하나씩 차례로 각 정점으로 들어오는 간선의 왼쪽 끝 정점까지
[3] 계산된 경로의 길이들 중에서 가장 긴 것에 1을 더하여 (끝 정점 +1) 경로의 길이를 계산
[4] 각 점의 경로 길이 중에서 가장 긴 것을 리턴한다.
시간 복잡도
그래프 만드는데 n(n-1)/2
좌에서 우로 들어오는 간선에 대한 연산량 = 그래프의 간선 수
알고리즘의 수행 시간 O(n^2)
코드
Bellman-Ford 최단 거리 알고리즘
설명
다익스트라 최단 경로 알고리즘의 문제점:
이미 확정된 점들에 대한 간선 완화를 수행하지 않음, 그리디 알고리즘은
한번 선택하여 확정된 값에 대해 수정을 허락하지 않기 때문
음수 사이클: 사이클 상의 간선의 가중치의 합이 음수인 사이클
반복할수록 거리 짧아져서 최단 경로 찾는 문제 성립 X
따라서 최단 경로 찾는 알고리즘에 음수 사이클은 존재 X
선형 그래프의 출발점부터 시작해서 좌에서 우로 간선 완화를 단계적으로 수행
일괄 처리 수행, 간선 완화 1회 시도할 때마다 모든 점이 간선 완화 시도에 참여
Bellman-Ford 알고리즘이 작은 것부터 풀어보기 방식인 이유:
그래프는 한눈에 부분 문제 확인하기 어렵지만 시작점이 가장 작은 문제
직전 점까지의 해를 찾은 후 그 다음 최단 경로가 확정되기 때문
알고리즘
<i, j> i부터 j까지 라는 뜻
D[j]가 저거보다 더 크다면, 더 작아질 수 있으므로
D[j]를 D[i] + 간선 <i, j>의 가중치로 바꿔서 간선 완화
반복하면서 업데이트 함(간선 완화), 왼쪽에서 오른쪽으로 n-1회 수행
시간 복잡도
각 간선에 대해 n-1회 간선 완화 수행
간선 수가 m이면 수행 시간은 O(mn)
그래프를 인접 행렬로 사용하면 O(n^2)
코드
서열 정렬
설명
어느 DNA가 다른 DNA로 변형되는데 얼마나 많은 변이가 필요한가 계산하는 문제
변이는 삽입, 삭제, 대체의 연산
ex) 문서 편집기: 스트링 S를 수정하여 스트링 T로 변환시킬 때 사용
편집 거리를 최소화하는 문제: (편집 거리: S를 T로 변환시키는데 최소 편집 연산 횟수)
앞부분에서 최적을 발견한 상태에서 뒷부분 해결
부분 문제 E[i, j] = S의 접두부(맨 앞)의 i개 문자를 T의 접두부 j개 문자로 변환시키는 데 필요한
최소 연산 횟수
E[i, j] 연산 방법: 세 방향에서 계산하는데 이 중 가장 작은 min값을 계산함.
단, 부분 -> si와 tj가 다르면 대체연산 1, 같으면 그대로니까 0
알고리즘
2차원 mn (ST) 리스트 E를 첫 번째 행부터 차례로 각 원소에 주변 3개의 해로
계산된 결과 중에서 최솟값을 저장한다.
return E[m, n]
위쪽에서 오면 삭제, 왼쪽에서 오면 삽입, 대각선에서 오면 대체orX변화
시간 복잡도
O(m*n)
코드
'알고리즘 코드' 카테고리의 다른 글
3. 욕심내어 풀어보기 (greedy) (0) | 2024.07.16 |
---|---|
2. 나누어 풀어보기 (0) | 2024.07.04 |
1. 순환과 기본적인 알고리즘 (0) | 2024.07.02 |