문제 개요 주어진 격자(grid)의 왼쪽 위 모서리에서 출발해 오른쪽 아래 모서리에 도달해야 합니다. 격자의 각 칸에는 숫자가 하나씩 들어 있는데, 이 값은 양수일 수도 있고 음수일 수도 있습니다. 사람이 어떤 칸 (i, j)에 도착하면, 그가 보유한 토큰 수는 해당 칸의 값만큼 증가하거나 감소합니다. 우리가 구해야 할 것은 이 여정을 끝까지 완주하기 위해 처음에 가져가야 하는 최소 초기 토큰 수입니다. 이동 규칙 이동 방향: 오른쪽 또는 아래로만 이동할 수 있습니다. 진입 조건: 보유한 총 토큰이 칸 (i, j)의 값보다 적으
플로이드-워셜 알고리즘이란?플로이드-워셜(Floyd-Warshall) 알고리즘은 가중치 그래프에서 모든 정점 쌍 사이의 최단 경로를 한 번에 구하는 대표적인 동적 계획법(Dynamic Programming) 기반 알고리즘입니다. 알고리즘을 수행하면 그래프 안의 어떤 노드에서 다른 모든 노드까지의 최소 거리가 담긴 행렬이 생성됩니다.다익스트라 알고리즘이 하나의 시작 정점을 기준으로 최단 거리를 구하는 것과 달리, 플로이드-워셜은 단 한 번의 실행만으로 모든 정점 쌍의 최단 거리를 계산할 수 있다는 점이 큰 강점입니다.동작 원리처음에
피보나치 수열(Fibonacci Sequence)은 다음과 같은 형태를 가지는 수열입니다.0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ……이 수열에서 n번째 항은 바로 앞의 두 항, 즉 (n-1)번째 항과 (n-2)번째 항의 합으로 정의됩니다.피보나치 수열을 생성하는 방법에는 재귀(recursion)를 사용하는 접근법도 있지만, 동적 프로그래밍(Dynamic Programming)을 활용하면 훨씬 더 간단하고 효율적으로 처리할 수 있습니다. 지금까지 계산한 모든 피보나치 수를 배열(테이블)에 저장해 두면, 이미
키보드로 문자 A를 입력하는 상황을 가정해 보겠습니다. 목표는 A, C, V, Ctrl 단 네 개의 키만 사용하여 텍스트 화면에 최대한 많은 A를 출력하는 것입니다.가장 많은 A를 만들기 위해서는 Ctrl + A(전체 선택), Ctrl + C(복사), Ctrl + V(붙여넣기) 조합을 전략적으로 활용해야 합니다.문제 이해하기6번 이하의 키 입력에서는 매번 A 키를 직접 누르는 것이 최선입니다. 하지만 7번부터는 중간에 전체 선택 → 복사 → 붙여넣기를 수행하는 것이 더 유리해집니다. 예를 들어, 7번의 키 입력이 주어지면 다음 순서
독립 집합(Independent Set)이란?독립 집합(Independent Set)은 이진 트리의 노드들 중에서, 집합에 속한 어떤 두 노드 사이에도 간선(연결 관계)이 존재하지 않는 노드들의 부분 집합을 의미합니다.즉, 주어진 원소들을 이용해 이진 트리를 구성했을 때, 서로 직접 연결되어 있지 않은 노드들만으로 이루어진 가장 큰 부분 집합을 찾는 것이 이 문제의 목표입니다.입력 및 출력입력:이진 트리출력:가장 큰 독립 집합의 크기: 5알고리즘 설계이 알고리즘에서는 이진 트리를 구성하며, 각 노드는 데이터(data)와 setSiz
정수로 이루어진 배열이 주어졌을 때, 연속된 요소들로 구성된 부분 배열(subarray) 중 그 합이 가장 큰 값을 찾아 출력하는 것이 이 문제의 목표입니다.이 문제는 동적 계획법(Dynamic Programming), 특히 카데인 알고리즘(Kadanes Algorithm)을 활용하면 선형 시간 안에 효율적으로 해결할 수 있습니다. 핵심 아이디어는 현재 위치까지의 최대 합을 계속 갱신하며 저장하는 것입니다.문제 예시입력: 정수 배열 {-2, -3, 4, -1, -2, 1, 5, -3}출력: 부분 배열의 최대 합은 7위 예시에서 최대
최장 공통 부분 수열(LCS)이란? 최장 공통 부분 수열(Longest Common Subsequence, LCS)은 주어진 두 문자열 또는 배열에 모두 포함되어 있는 부분 수열 중 길이가 가장 긴 것을 찾는 고전적인 알고리즘 문제입니다. 여기서 부분 수열(subsequence)은 원래 문자열에서 문자의 상대적인 순서를 유지한 채 일부 문자를 제거해 만든 수열을 의미하며, 반드시 연속적일 필요는 없습니다. 예를 들어 AGGTAB과 GXTXAYB의 최장 공통 부분 수열은 GTAB이며, 그 길이는 4입니다. 이 문제를 단순 재귀로 풀면
바이토닉(bitonic) 수열은 처음에는 증가하다가 이후에는 감소하는 형태의 수열을 말합니다. 이 문제에서는 양의 정수로만 이루어진 배열이 주어지며, 그중에서 먼저 증가한 뒤 감소하는 부분 수열(subsequence)을 찾아 그 최대 길이를 구해야 합니다.이 문제를 해결하기 위해 두 개의 보조 배열을 정의합니다. 하나는 최장 증가 부분 수열(LIS, Longest Increasing Subsequence), 다른 하나는 최장 감소 부분 수열(LDS, Longest Decreasing Subsequence)입니다. LIS 배열은 ar
문제 개요서로 다른 문자들로 구성된 행렬이 주어집니다. 하나의 문자에서 시작하여, 현재 문자보다 알파벳 순서상 정확히 한 단계 뒤에 오는 문자(예: a → b, b → c)를 따라 인접 칸으로 이동할 때 만들 수 있는 가장 긴 연속 경로의 길이를 구하는 것이 목표입니다.이동은 상하좌우뿐 아니라 대각선 방향을 포함한 총 8방향의 인접 칸으로 가능하며, 각 이동 시 문자는 반드시 연속되어야 합니다.해결 접근 방법이 문제는 깊이 우선 탐색(DFS)으로 해결할 수 있습니다. 그러나 DFS를 수행하는 과정에서 동일한 부분 문제(subprob
가장 긴 증가 부분 수열(Longest Increasing Subsequence, LIS)은 수열 내에서 각 원소가 자신의 앞 원소보다 큰 값을 갖도록 유지되는 부분 수열입니다. 이 글에서는 주어진 정수 집합에서 가장 긴 증가 부분 수열의 길이를 찾는 방법을 알아보겠습니다. 문제 이해하기 LIS 문제는 원본 배열의 순서를 그대로 유지한 채 일부 원소를 골라내어, 선택된 원소들이 오름차순이 되도록 만들 때 선택할 수 있는 최대 개수를 구하는 것입니다. 반드시 연속된 구간일 필요는 없으며, 떨어져 있는 원소들을 조합할 수 있다는 점이
주어진 문자열 안에서 회문(palindrome)이 되는 부분 문자열 중 가장 긴 것을 찾는 것이 이번 문제의 목표입니다.가장 긴 회문 부분 문자열을 구하는 과정에서는 수많은 하위 문제(subproblem)를 풀게 되는데, 일부 하위 문제는 서로 겹쳐 있어(overlapping) 같은 계산을 여러 번 반복해야 할 수 있습니다. 바로 이런 경우 동적 프로그래밍(Dynamic Programming)이 큰 힘을 발휘합니다. 테이블을 활용해 이전에 계산한 하위 문제의 결과를 저장해 두면, 이후에는 저장된 값을 그대로 재사용하여 다음 결과를
각 칸에 포인트가 배치된 행렬(그리드)이 주어졌을 때, 두 번의 순회(traversal)를 통해 얻을 수 있는 최대 포인트를 구하는 방법을 알아보겠습니다.문제 조건이 문제를 해결하려면 다음 세 가지 조건을 만족해야 합니다.첫 번째 순회는 그리드의 왼쪽 위 칸에서 시작하여 왼쪽 아래 모서리로 이동하고, 두 번째 순회는 오른쪽 위 모서리에서 시작하여 오른쪽 아래 모서리로 이동합니다.한 칸에서 다음 칸으로 이동할 때는 현재 칸 기준으로 아래, 왼쪽 아래 대각선, 오른쪽 아래 대각선 방향만 가능합니다.첫 번째 순회에서 이미 포인트를 획득한
문제 개요이 문제는 1부터 n까지 범위에 있는 모든 숫자의 자릿수 합을 구하는 것입니다. 예를 들어 54의 자릿수 합은 5 + 4 = 9입니다. 이처럼 범위 내의 모든 숫자에 대해 각각 자릿수 합을 구한 뒤, 그 전체 합을 계산해야 합니다.단순히 1부터 n까지 하나씩 확인하는 방법도 있지만, n이 매우 커지면 비효율적입니다. 다행히 자릿수가 d개인 숫자는 총 10d-1개 존재한다는 사실을 활용하면, 재귀 공식을 통해 훨씬 빠르게 답을 구할 수 있습니다.재귀 공식1부터 10d − 1까지 모든 숫자의 자릿수 합을 sum(10d − 1)
이 문제에서는 연속된 1을 포함하지 않는 이진 문자열의 개수를 구해야 합니다. 예를 들어 3비트 이진 문자열 중에는 011, 110, 111처럼 연속된 1을 가진 세 가지가 있으며, 나머지 다섯 가지(000, 001, 010, 100, 101)는 연속된 1이 없습니다. 따라서 3비트에 이 알고리즘을 적용하면 답은 5가 됩니다.a[i]를 비트 수가 i이면서 연속된 1을 포함하지 않는 이진 문자열들의 집합, b[i]를 비트 수가 i이면서 연속된 1을 포함하는 이진 문자열들의 집합이라고 정의하면, 다음과 같은 점화식이 성립합니다.a[i]
플레이어가 한 번의 이동마다 3점, 5점 또는 10점을 얻을 수 있는 게임이 있다고 가정해 봅시다. 목표 점수가 주어졌을 때, 우리의 과제는 이 세 가지 점수 조합을 사용하여 해당 목표 점수에 도달할 수 있는 경우의 수를 구하는 것입니다.이 문제는 동적 계획법(Dynamic Programming)으로 효율적으로 해결할 수 있습니다. 핵심 아이디어는 0부터 n까지의 모든 점수 값에 대한 경우의 수를 저장하는 테이블을 만들고, 3, 5, 10 각각의 점수를 순서대로 적용하며 테이블을 갱신하는 것입니다.입력 및 출력입력:3, 5, 10을
문제 정의 도로변에 n개의 구역이 주어져 있으며, 각 구역은 도로를 기준으로 양쪽 두 면에 건물을 지을 수 있습니다. 단, 두 집 사이에는 최소 한 칸의 빈 공간이 있어야 한다는 조건이 붙습니다. 이때 이 부지 전체에 건물을 배치할 수 있는 경우의 수는 총 몇 가지일까요? 하나의 구역을 기준으로 보면 건물을 짓는 방식은 다음 네 가지로 나눌 수 있습니다. 도로의 한쪽 면에만 건설 도로의 반대쪽 면에만 건설 아무 건물도 짓지 않음 도로 양쪽 면 모두에 건설 입력 및 출력 프로그램은 건물을 지을 구역의 개수 n을 입력으로 받습니다
문제 개요계단이 n개 있다고 가정해 봅시다. 한 사람이 1번째 계단부터 시작하여 n번째 계단까지 올라가려고 하며, 한 번에 최대 몇 개의 계단을 뛰어넘을 수 있는지도 주어집니다. 이 정보를 바탕으로 n번째 계단에 도달할 수 있는 모든 경우의 수를 구하는 것이 이 문제의 목표입니다.예를 들어 한 번에 최대 두 개의 계단까지 오를 수 있다고 생각해 보겠습니다. 그렇다면 재귀 관계식을 세워 문제를 해결할 수 있습니다. n번째 계단에 도달하는 방법은 두 가지뿐입니다. (n-1)번째 계단에서 한 칸 오르거나, (n-2)번째 계단에서 두 칸
문제 개요계란 떨어뜨리기(Egg Drop) 퍼즐은 알고리즘 분야에서 가장 유명한 고전 문제 중 하나입니다. n층으로 이루어진 건물과 m개의 계란이 주어졌을 때, 계란을 떨어뜨려도 깨지지 않는 안전한 층을 찾기 위해 필요한 최소 시도 횟수를 구하는 것이 목표입니다.핵심 조건특정 층에서 계란이 깨지지 않았다면, 그보다 낮은 층에서도 반드시 깨지지 않습니다.특정 층에서 계란이 깨졌다면, 그보다 높은 모든 층에서도 반드시 깨집니다.한 번 깨진 계란은 폐기해야 하며, 깨지지 않은 계란만 다시 사용할 수 있습니다.입력 및 출력 형식입력:계란의
편집 거리란 무엇인가?두 개의 문자열이 주어졌을 때, 첫 번째 문자열은 소스(source) 문자열, 두 번째 문자열은 타겟(target) 문자열이라고 합니다. 편집 거리(Edit Distance) 알고리즘은 소스 문자열을 타겟 문자열로 변환하는 데 필요한 최소 편집 횟수를 구하는 문제입니다.여기서 말하는 편집은 다음 세 가지 연산 중 하나를 의미합니다.삽입(Insert) — 새로운 문자를 추가삭제(Delete) — 기존 문자를 제거수정(Modify) — 기존 문자를 다른 문자로 변경입력과 출력프로그램은 비교할 두 문자열을 입력받고,
자릿수 n과 목표 값(sum)이 주어졌을 때, 각 자릿수의 합이 주어진 값과 정확히 일치하는 모든 n자리 숫자를 찾는 문제입니다. 이때 0은 자릿수로 계산하지 않으며, 첫 번째 자리에는 0이 올 수 없습니다.제약 조건은 다음과 같습니다.자릿수 n: 1 이상 100 이하목표 값: 1 이상 500 이하입력 및 출력 예시입력: 자릿수와 목표 합을 입력받습니다. 예를 들어 자릿수가 3이고 합이 15인 경우 출력: 각 자릿수의 합이 15가 되는 서로 다른 3자리 숫자의 개수를 출력합니다. 결과는 69입니다. (즉, 자릿수의 합이 15인 3