본문 바로가기

분류 전체보기

(694)
부분 합. [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. 코드]
분할 정복 솔루션 [1. 개요] 문제를 한 조각과 나머지 전체로 나누는 완전 탐색과 달리 거의 같은 크기의 부분 문제로 나누는 점에서 분할 정복은 완전 탐색과 다르다고 볼 수 있다. 분할 정복을 사용하는 알고리즘은 보통 아래와 같은 형태로 구성된다. 문제를 분할 하는 과정 (Divide) 분할하여 해결 한 답을 전체의 답으로 병합하는 과정 (Merge) 더 이상 분할하지 않고 바로 풀 수 있는 작은 문제 (Base case) => 꼭, 더 이상 분할 할 수 없는 경우가 아니더라도 => 이 구간 혹은 이번 부분 문제에서 원하는 답을 구할 수 없겠다 싶으면, => 더 이상 분할하지 않고 넘어 갈 수 있다. 단, 이 구간에서 초기화 해야 될 값이 있으면, 스킵으로 인해 이 값이 적절히 초기화는 시켜주어야 한다. 구현 패턴 기저..
완전 탐색. [2798] [1. 문제 설명] https://www.acmicpc.net/problem/2798 [2. 풀이 접근] 시간 복잡도 분석 전체 100 개 중 3 가지를 선택해야 함. => 100C3 그러나 특정 조건을 만족해야 함. => 반드시 3개를 선택 하고 그 합이 M 을 넘지 않아야 함. 이 조건을 통해 가지치기가 가능 함 기저 사례 혹은 가지 치기 할 수 있는 경우 3가지 카드를 선택 한 경우. (가지 치기) => 현재까지 합이 M 이하인 경우, 누적 합을 반환. => 현재까지 합이 M 초과한 경우, 0을 반환. 이번에 선택 할 아이템이 배열의 범위를 벗어난 경우 (기저 사례) => 0을 반환. 현재까지 합이 M 을 초과한 경우. (가지 치기) => 0을 반환. 문제 조건 상 반드시 3가지 카드는 선택되어야 ..
완전 탐색. [14501] [1. 문제 설명] https://www.acmicpc.net/problem/14501 [2. 풀이 접근] 시간 복잡도 계산 금일 상담을 선택 => 금일 상담을 퇴사 전까지 할 수 있는 경우에만 선택하도록 한다. 금일 상담을 하지 않고, 다음 날로 이동 매일 2가지 선택이 존재하므로, O(N2) N 의 최대 값은 15 이므로, 총 경우의 수는 대략 32000개 이므로, 시간 내 풀이 가능 [3. 코드]