알고리즘 13

[C++] 백준 알고리즘 10828번 : 스택 - 풀이 코드

10828번: 스택 첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 www.acmicpc.net 문제 정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오. 명령은 총 다섯 가지이다. push X: 정수 X를 스택에 넣는 연산이다. pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다. size: 스택에 들어있는 정수의 개수를 출력한다. empty: 스택이 비어있으면 1, 아니면 0을 출력한다. top: 스택의 가장 위에 있는 정..

[알고리즘] 되추적 알고리즘, Backtracking

backtracking은 깊이우선탐색(DFS) 방식으로 상태공간트리를 탐색하는 알고리즘으로, 최적화 문제를 해결하는데에 사용될 수 있다. backtracking의 진행절차는 다음과 같다. ① 상태공간트리의 깊이우선검색(DFS)을 실시 ② 각 노드가 유망(promising)한지 점검 ③ 유망하지 않은 노드들은 더 이상 검색하지 않고 그 노드의 부모노드로 돌아가서 검색을 계속(pruning), 유망한 노드들은 그 노드의 자식노드를 검색 여기서 promising, 즉 유망하다는 것은 더 내려다볼 가치가 있다는 것이고 반대로 유망하지 않다(non-promising)는 것은 전혀 해답이 나올 가능성이 없다는 것을 의미한다. 유망하지 않으면 그 자식노드에 대한 탐색을 중단하고 부모노드로 돌아가는데, 이를 '가지친다..

[알고리즘] 탐욕 알고리즘, The Greedy Approach

미래의 결과를 예측할 수 없는 상황에서 지금 내가 할 수 있는 최선의 결정은 무엇일까? 매 선택마다 그 순간에 가장 좋다고 생각되는 것을 선택하는 것이다. 즉, 그 순간에 가장 좋다고 생각되는 것을 선택함으로써 최종적인 해답에 도달한다. 매 순간 가장 좋다고 생각되는 것을 선택하면 그것이 궁극적으로도 최적이 될 수도 있기 때문이다. 이러한 원리의 접근방식이 바로 Greedy Approach이다. 하지만 이는 미래를 고려하지 않고 단지 그 순간에서의 optimal한 것을 선택한 것이므로, 그 해답이 궁극적으로 optimal라는 보장이 없다. 따라서 최적의 해답을 주는 알고리즘인지 검증하는 과정이 반드시 필요하다. 따라서 Greedy Approach 알고리즘의 구성은 다음과 같다. ① 선택 절차, selec..

[알고리즘] 외판원 문제, TSP(The Traveling Salesperson Problem) | 설계 및 분석

외판원 문제란? home city에서 출발해 모든 city를 한번씩 거치고 다시 home city로 돌아오는 최단 경로를 구하는 문제이다. 만약 무식하게 모든 경우의 수를 다 알아본 후 가장 짧은 경로를 찾는다면 그 성능은 어떻게 될까? (n - 1)! 즉 O(n!)이라는 결과가 나온다. 이렇게 비효율적인 방법은 쓸모가 없으므로 우리는 동적계획법을 사용하여 TSP를 풀어보려고 한다. ① W : 그래프의 인접행렬 W[i][j] = 이음선의 가중치 (vi에서 vj로의 이음선이 있는 경우) = ∞ (vi에서 vj로의 이음선이 없는 경우) = 0 ( i = j인 경우 ) ② V : 모든 정점들이 담긴 집합 ③ A : V의 부분집합 ④ D[vi][A] : vi에서 A의 집합들을 한번씩 모두 지나면서 v1로 가는 ..

[알고리즘] 최적 이진 검색 트리, Optimal Binary Search Trees | 설계 및 분석

최적 이진 검색 트리란? 최적 이진 검색트리의 뜻을 알기위해서는 먼저 이진 검색 트리의 뜻을 알아야한다. 이진 검색 트리는 말 그대로 이진 트리를 검색 목적으로 사용하는 것이다. 왼쪽에는 같거나 더 작은 값을, 오른쪽에는 더 큰 값을 저장하고 leaf 노드들 간의 depth 차이가 1보다 클 수 없다. 여기서 '최적'이란 단어까지 붙으면 최적 이진 검색트리가 된다. 최적 이진 검색 트리는 가능한 이진 검색 트리 중 key를 찾는데에 걸리는 평균 시간이 가장 짧은 이진 검색 트리를 의미한다. 탐색시간은 원하는 키를 찾기까지 필요한 비교 횟수이다. 평균 탐색시간은 한 노드에 담긴 keym이 찾고자하는 search key일 확률을 pm라고 하고, keym을 찾기까지의 비교횟수를 cm이라고 할 때 pm과 cm의..

[알고리즘] 플로이드 알고리즘, Floyd's Algorithms | 설계 및 분석 , 구현코드

플로이드 알고리즘이란? 한 도시에서 다른 도시로 가는 직항로가 없는 경우 가장 빨리 갈 수 있는 항로를 찾는 shortest path 문제들 중 하나이다. 플로이드 알고리즘은 가중치 포함 그래프의 각 정점에서 다른 모든 정점까지의 최단 거리를 구한다. 플로이드 알고리즘이 shortest path 문제들 중 한 유형이므로, 플로이드 알고리즘을 살펴보기 전에 shortest path의 특징을 먼저 알아볼 필요가 있다. ① W : 그래프의 인접행렬 W[i][j] = 이음선의 가중치 (vi에서 vj로의 이음선이 있는 경우) = ∞ (vi에서 vj로의 이음선이 없는 경우) = 0 ( i = j인 경우 ) ② D(k) : 각 정점들 사이의 최단거리 (floyd 알고리즘에서 고안) k : 중간에 거쳐갈 수 있는 정점..

[알고리즘] 이항계수, Binomial Coefficient | 설계 및 분석

이항계수라하면 고등학교 때 잠깐 나타나고 말 것인줄 알았거늘..... 여기서 또 마주치다니 우리에게 너무나도 익숙한 이 이항계수 nCk 어쩌구 저쩌구가 동적 계획법과 어떤 관련이 있다는건지 알아보자..^^ 이항계수란? 이항계수는 n개의 원소중에서 k개를 순서에 상관없이 뽑았을 때 조합의 가짓수이다. 파스칼의 삼각형을 이용한 이항계수의 성질은 다음과 같다. nCk = n-1Ck-1 + n-1Ck 위 식과 그림을 보면 알 수 있듯, 파스칼 삼각형에서 n-1번째 줄 k-1번째 수와 n-1번째 줄 k번째 수를 합한 값이 n번째 줄 k번째 수의 값이 된다. 즉, 이전 항들의 수의 합이 다음 항의 수가 된다. 이는 전체 문제의 부분들이 서로 상관관계가 있다는 것이고, 따라서 이항계수는 dynamic programm..

[알고리즘] 동적계획법, Dynamic Programming

dynamic programming는 divide-and-conquer와 마찬가지로 재귀적인 속성을 가지고있지만, 더 나아가 최적화 문제를 다룬다는 특징 또한 가지고있다. 최적화 문제란 주어진 문제에 대하여 하나 이상의 많은 해답이 존재할 때 이 가운데에서 가장 최적인 해답을 찾아야 하는 문제를 일컫는다. 따라서 재귀적인 속성에 최적화 문제인 경우 dynamic programming으로 해결하면 된다. dynamic programming은 bottom-up 방식을 이용하여 재귀적인 문제를 해결한다. 즉, 입력 사이즈가 제일 작은 문제부터 해결하여 점점 큰 문제를 해결해나가고, 이 때 나누어진 부분들 사이에는 서로 상관관계가 있다. dynamic programming 과 divide-and-conquer의..

[알고리즘] 퀵 정렬, Quick Sort | 설계 및 분석

퀵 정렬 알고리즘이란? 선정된 pivot값을 기준으로 배열을 나누어가면서 재귀적으로 정렬하는 알고리즘 알고리즘 설계 전략 pivot을 선정한다. pivot 보다 작은 값은 왼쪽, 더 큰 값은 오른쪽에 배치한다. 양쪽 배열에 대해 다시 같은 과정을 반복함으로써 최종적으로 배열을 정렬한다. 알고리즘 수도코드 void quicksort(index low, index high) { index pivotpoint; if(high > low) { partition(low, high, pivotpoint); //배열을 pivot 값을 기준으로 반으로 나눈다. quicksort(low, pivotpoint-1); // 왼쪽 배열에 대해 재귀적으로 정렬 quicksort(pivotpoint+1,high); // 오른쪽 ..

[알고리즘] 합병 정렬, Merge Sort | 설계 및 분석

합병 정렬 알고리즘이란? 크기가 n인 배열을 원소가 하나 밖에 남지 않을 때까지 계속 반으로 쪼갠 후 다시 크기 순으로 정렬 하면서 원래 크기의 배열로 합치는 정렬 알고리즘 알고리즘 설계 전략 배열 원소가 하나 남을 때 까지 배열을 재귀적으로 쪼갠다. (Divide) 쪼개진 배열들을 정렬하면서 다시 합친다. (Conquer) 알고리즘 수도코드 void mergesort(int n, keytype S[]) { if (n > 1) { const int h = ⌊n/2⌋, m= n - h; keytype U[1..h], v[1..m]; //S를 반으로 쪼개 왼쪽은 U에 오른쪽은 V에 저장 copy S[1] through S[h] to U[1] through U[h]; copy S[h+1] through S[n..