본문 바로가기

알고리즘

(405)
스택 관련 문제 솔루션 [1. 개요] fd [2. 예제] https://testkernelv2.tistory.com/539 https://testkernelv2.tistory.com/540 c d e f
스택. [1406] [1. 문제 설명] https://www.acmicpc.net/problem/1406 [2. 풀이 접근] 연결 리스트를 이용하여 푸는 방법 => 반복자를 커서로 사용한다. 스택을 이용한 풀이 방법 => 여기서는 스택을 이용한 풀이를 정리한다. 구현 컨셉 두 개의 스택을 준비한다. 한쪽 stack (lStack) 의 top 은 커서의 왼쪽 문자를 가리킨다. 반대쪽 stack (rStack) 의 top 은 커서의 오른쪽 문자를 가리킨다. 명령어를 처리한다. L: lStack 의 top 을 제거하고, rStack 에 push 한다. D: rStack 의 top 을 제거하고, lStack 에 push 한다. B: lStack 의 top 을 제거한다. P: 새로운 문자를 lStack 에 push 한다. 출력, 재..
부분 합 솔루션 [1. 개요]공식pSum[i] = A[i] - pSum[i-1]구간 [a, b] 의 원소들의 합sum[a~b] = pSum[b] - pSum[a-1]a-1 의 원소의 접근해야 할 필요가 있으므로,구현의 편의 성을 위해 배열은 0이 아닌 1부터 시작하도록 하는 것이 좋다.이러한 개념은 2차원 배열로도 확장 된다. 2차원 배열 상에서 부분 합이 살짝 까다로울 수 있다.단순 넓이 개념으로 생각하면 아래와 같이 구할 수 있다. pSum[y,x] 를 [0,0] ~ [y,x] 내 속한 원소의 합으로 생각하는 것이다.link 463 예체 참조, [2. 예제]https://testkernelv2.tistory.com/463https://testkernelv2.tistory.com/534https://testkernel..
부분 합. [2167] [1. 문제 설명]https://www.acmicpc.net/problem/2167[2. 풀이 접근]문제의 요구 사항은 다음과 같다.입력으로 주어진 i, j, x, y 가 배열 상에서 아래와 같은 그림과 같을 때다음과 같은 영역의 존재하는 원소들의 합을 구하는 것 이다.단순한 풀이, 매 TC 마다 배열의 구간 [i, j] ~ [x, y] 를 iterate 하면서 그 합을 구한다면,전체 시간복잡도가 O(N*M*10000) 이고, 대략 300*300*10000 = 9*108 ==> 1초가 넘어 갈 수 있다. 그러나 각 행마다 그 부분 합 들을 따로 구해 놓으면,300*10000 = 3*106 으로 시간 복잡도를 대폭 줄일 수 있다. 각 행에 대해서는 루프를 돌지만, 그 행의 합은 O(1) 에 구할 수 있게 ..
탐욕법. [1026] [1. 문제 설명] https://www.acmicpc.net/problem/1026 [2. 풀이 접근] 완전 탐색 시 시간복잡도는 N! => 현실적인 시간내에서 해결이 불가능함. 두 수의 곱들의 합을 최소로 만들기 위한 방법을 생각해보면 문제 조건 상 두 수의 곱이 음수가 될 수 없다. 즉, 모든 두 수의 곱이 최소가 되도록 하면 된다. 수열 B 의 순서는 재배열하지 않는다고 적혀있지만, 정렬해도 된다. (단, 수열 A 를 출력하라고 한다면, 원래 위치를 따로 저장 할 필요가 있다.) 정렬 후 수열 B 의 앞쪽에 오는 숫자는 가장 작은 값 이다. 여기에 수열 A 에서 가장 큰 값을 곱하도록 한다. 가장 작은 값을 곱하면, 수열 B의 가장 큰 값에 수열 A 에서 가장 큰 값이 곱해 질 수 있다. => 큰..
이분탐색 솔루션 [1. 개요] 보통 매우 큰 범위를 갖는 어떤 값 중 최적 값을 찾을 때 유용하다. N 이 [0, 1,000,000,000] 사이의 값일 때, 어떤 식을 최대 혹은 최소로 만드는 N 을 구한다. 완전 탐색 시, 시간 초과가 당연하다. 그러나 이 범위에서 이분 탐색을 하면, 32번 이내로 찾을 수 있다. => 어떤 조건을 만족하는 최대 N 을 구해야 할 때 => 먼저 중간 값을 찾고, 이 값을 주어진 식에 대입 => 특정 조건을 만족하면 상위 구간에서 이분 탐색 진행 => 만족하지 않으면 하위 구간에서 이분 탐색 진행 주의 할점 범위와 반복문 조건이 중요하다. (구간 및, 반복문 조건 (등호 유무) 등이 다르면 틀린다.) => 구간은 보통 [a, b], 폐구간 이어야 한다. => 그래서 반복문 조건은 wh..
탐욕법 솔루션 [1. 개요] 완전 탐색, 동적 계획법과 같이 전체 문제를 여러 개의 부분 문제로 나누고, 각 부분 문제를 해결하는 것 까지는 같으나, 각 단계마다 지금 당장 좋은 방법만을 선택한다는 것에서 다르다. 즉, 현재 선택이 앞으로 남은 선택들에 어떤 영향을 끼칠지는 고려하지 않는다. 탐욕법을 사용하는 경우 탐욕법을 사용해도 항상 최적해를 구할 수 있는 경우 => 이때는 완전 탐색, 동적 계획법 등으로 풀 수 없는 경우라고 볼 수 있다. => 보통 완전탐색, 동적 계획법으로 구현 시 제한 시간 이내로 풀 수 없는 경우. => 약간의 직관력이 필요하다. 탐욕 알고리즘에 대한 증명은 보통 일정한 패턴을 갖는다. 탐욕적 선택 속성 => 탐욕적 선택을 해서 손해 볼 일은 없다. => 귀류법을 사용하여 증명 최적 부분 ..
동적계획법. [11726] [1. 문제 설명] https://www.acmicpc.net/problem/11726 [2. 풀이 접근] 완전 탐색에서 시작한다. 맨 왼쪽을 2x1 타일 1개로 채우고, 나머지 2x(n-1) 타일에 대한 부분 문제를 해결한다. 맨 왼쪽을 2x2 타일 2개로 채우고, 나머지 2x(n-2) 타일에 대한 부분 문제를 해결한다. 두 경우의 합을 반환한다. 기저 사례 => 길이가 0 인 경우: 모든 타일을 채움 => 1을 반환 => 하나의 경우를 완성하였다. => 길이가 음수인 경우: 타일을 채울 수 없음 => 0을 반환 이 문제는 최적화 문제는 아니다. 그러나 전체 타일 길이 N에 대해서 앞의 [0, N-A) 를 어떻게 채우던 간에 [N-A, N) 을 채우는 문제는 한번만 계산하면 된다. 그래서 메모이제이션을..
동적계획법 솔루션 [1. 개요] 일반적인 접근 방식 완전 탐색에서 시작한다. => 완전 탐색 코드를 먼저 작성 => 중복되는 문제에 대한 메모이제이션을 적용. 보통 중복되는 부분문제들을 최초 한번만 계산하고, 나머지는 이 값을 재활용 한다. => 메모이제이션 => 최초 캐시 메모리는 -1 로 초기화 한다. (아직 이 부분 문제가 계산되지 않음을 의미한다.) => 캐시 메모리는 문제에서 주어진 공간 복잡도를 만족해야 한다. 메모이제이션 할 대상을 선정해야 한다. => 보통 캐시의 index 로 사용 함. => 부분 문제의 입력으로 주어지는 패턴을 갖는다. => 문제 입력의 범위를 보고 눈치껏 메모이제이션 할 대상을 선정해야 한다. => 특히, 캐시를 다차원 배열로 해야하는 경우 최적화 문제 => 여러개의 가능한 답 중 가장..
분할 정복. [1074] [1. 문제 설명] https://www.acmicpc.net/problem/1074 [2. 풀이 접근] 전체 행렬을 4등분하여 순서대로 탐색하는 전략을 취한다. 여기서 주의 할 부분은 매 단계 마다 4개의 부분문제가 생겨나므로, 최대 415 개의 부분문제가 생길 수 있다. 그래서 이번에 해결할 부분문제가 입력으로 주어진 row 와 col 을 포함하지 않으면 과감히 버리도록 하여 시간을 절약 하도록 한다. 물론, 종료 하기 전 방문 순서는 업데이트 해야 하며, 이번 구간에서 방문해야 할 총 개수는 행렬의 길이의 제곱인 것이 자명하므로, 쉽게 업데이트 할 수 있다. [3. 코드]