목록알고리즘 (57)
Joonas' Note
링크: https://www.acmicpc.net/problem/5535문제각 날짜마다 입을 수 있는 옷들이 있고, 다음 날과 옷의 화려함의 차이가 최대한 크도록 옷을 고르는 문제이다.날짜마다 가능한 옷을 저장해둔다. 그 날에 한해서는 옷의 종류나 순서가 중요치않길래 화려함 정도를 넣어버렸다. 이제 각 날짜마다 옷을 하나씩 고른다면, 총 D일동안 N가지의 옷을 고르므로 경우의 수는 \(O(N^{D})\) 이다. 어떤 d번째 날에 A라는 옷을 골랐다고 치자. 그럼 d+1번째 날 이후로는 d번째 날에 A를 고른 영향이 계속 생긴다.즉, d번째 날에 a를 고른 이후로는 하나의 부분 문제로 볼 수 있다. 점화식을 dp[D][N] = D번째 날에 N번째 옷을 선택했을 때의 화려함의 최대값 으로 세우면 \(O(ND..
문제2019년 초에 신년을 맞아 싱가포르 국립대학교(NUS) 천재들과의 문제 배틀이 있었다.그 중 하나로, 빨간 화살표가 가리키는 방향에는 빨간 화살표가 2개만, 회색 화살표가 가리키는 방향에는 빨간 화살표가 2개가 아니도록 화살표를 색칠하는 문제가 있었다.규칙을 만족하는 포인트를 파악해서 논리적으로 연결해나가는 것이 맞지만, 우리는 컴퓨터가 있다.무식하게 모든 경우를 전부 확인해보자. 정말 답이 하나일까? 세로 4행, 가로 5열 총 전체 20개의 칸을 모두 색칠해보는 경우는, 각 칸을 색칠한다/하지않는다 2가지의 선택이 20개 칸마다 있는 것이므로\(O(2^{20})\)이다. 색칠 후에는 각 화살표들이 모두 규칙을 만족하는 지 확인해야하므로 연산이 조금 더 붙지만, 그래도 3천만번 이하로 계산된다.이 ..
여기서 맞왜틀이란, "맞았는 데 왜 틀렸지?"에 줄임말입니다. 이 글은 알고리즘 문제 풀이(Problem Solving)를 하면서 종종 마주하는 "맞왜틀?"을 피하는 방법들을, 제가 아는 지식과 겪어본 경험을 토대로 정리해볼까 합니다. 코드의 구현과 관련한 깊은 내용들은 C/C++을 기준으로 이야기합니다. 문제를 푸는 환경 이제는 많은 문제 풀이 플랫폼과 온라인 저지 사이트들이 있습니다. 역사 깊은 UVa Online Judge부터 Algospot(알고스팟), Baekjoon Online Jubge, 프로그래머스까지 굉장히 다양하고 많아졌습니다. 각 사이트마다 채점 방식이나 결과가 다를 수 있으니, 이것을 먼저 찾아보고 이해하는 것이 좋습니다. 어떤 컴파일러로 채점하나요? 대부분의 사이트에서 C, C++..
링크: https://www.acmicpc.net/problem/2517문제최선의 등수는 다시 말하면, "a[k] = 어떤 k 입장에서 왼쪽으로 자신보다 높은 실력의 개수" 이다."왼쪽으로"의 뜻은 "이전까지 등장한"과 같은 말이고, 자신보다 높은 실력의 개수는 기록을 통해서 셀 수 있다.문제는 수의 범위가 1,000,000,000 이하라서 수를 직접 저장하기는 힘들어 보인다.문제 조건 중, 참가한 선수들의 실력은 모두 다르다는 조건이 있다. 그럼 같은 의미로 그 사람의 등수를 기록하자.N은 50만 이하이므로, 등장한 등수(rank)를 1로 기록하고 k 위치에서 자신보다 높은 실력(=등수)는 세그먼트 트리로 쉽게 셀 수 있다.선수 k의 최선의 등수는 query(자신의 등수 + 1, 범위 끝) + 1이다...
세그먼트 트리는 임의의 위치의 값들이 계속 변화하고, 특정 구간에 대한 연산(어떤 구간의 합, 어떤 구간 중 최소값 등)을 빠르게 구할 때 용이한 자료구조이다.한국어로는 구간 합 트리?라고도 하는 것 같다. 이 글을 적는 이유는 세그먼트 트리 자체를 다루기 위한 것은 아니고, 크기를 2배로 잡는 대신에 비재귀 형태로 간단하게 작성할 수 있는 코드를 소개하려고 한다.처음 접한 건 2016년 쯤 코드포스에서 읽었다. 워낙 간단하고 명료해서 아직까지 외우고 있다.링크: http://codeforces.com/blog/entry/18051대회에서도 자주 사용했는데, 블로그 포스팅은 한 적이 없어서 나중을 위해 다시 적어둔다. 자세한 설명은 원문 링크에 자세히 나와있으므로 생략한다.사용할 때 주의할 점은, que..
링크: https://www.acmicpc.net/problem/1308문제풀이 재활훈련을 시작했다.문제를 푸는 데 실수가 너무 많아진다..문제날짜, 시간 차이를 구하는 문제는 정수 하나로 변환해서 퉁 치는게 제일 편하다. (년/월/일 -> 총 X일)단, 조건 중에 천년을 넘어가면 gg를 출력해야하는데, 2000/05/05 ~ 2100/04/30 같은 경우는 천년을 넘기지 않음에 조심해야한다.코드
링크: https://www.acmicpc.net/problem/17520풀이균형잡힌 문자열에서 확인하는 모든 부분 문자열은 첫번째 문자를 포함한다. 즉, 앞에서부터 순차적으로 확인하여 0와 1의 개수가 1 이상 차이가 난다면 균형잡힌 문자열이 아니라는 뜻이다. 우선 무식하게 모든 경우의 수를 다 확인해볼 수 있다. i번째 위치를 0 또는 1로 결정하면서, 균형잡힌 문자열이 되는 경우만 탐색했다. n=3일 때, 010, 011, 100, 101 네 개의 문자열이 나온다. n=1부터 하나씩 확인해보면 \(2, 2, 4, 4, 8, 8, \dots, 2^{n-1}, 2^{n-1}, 2^{n}, 2^{n}\) 로 규칙성이 보인다. 이제 문제는 \(f(n)=2^{\lfloor{(n+1)}/2\rfloor}~mo..
링크: https://www.acmicpc.net/problem/1699문제주어진 N을 최소 몇 개의 제곱수의 합으로 표현할 수 있는 지 구하는 문제이다. 문제를 풀기 전에, 라그랑주 네 제곱수 정리를 알고 있으면 좋다. 백준 온라인 저지에 문제로도 등장했다. BOJ 3933 - 라그랑주의 네 제곱수 정리 요약하면, 모든 양의 정수가 많아야 4개의 제곱수의 합이라는 정리인데, 다시 말하면 이 문제의 정답은 최대 4라는 뜻이다. \(x^a + y^b + z^c + w^d = N\) 에서 \(a,~b,~c,~d\) 를 모두 확인해 볼 필요는 없다. 라그랑주의 정리에 의하면 모든 \(a,~b,~c\)를 찾았는 데 없으면 4개로 표현할 수 있기 때문이다. 즉, 3중첩 반복문으로 해결 가능하다.코드