다이나믹 프로그래밍
-
BOJ) 점프알고리즘/백준 2020. 8. 27. 15:30
점프 1890번: 점프 문제 N×N 게임판에 수가 적혀져 있다. 이 게임의 목표는 가장 왼쪽 위 칸에서 가장 오른쪽 아래 칸으로 규칙에 맞게 점프를 해서 가는 것이다. 각 칸에 적혀있는 수는 현재 칸에서 갈 수 있는 거�� www.acmicpc.net 풀이 0,0을 시작으로 n-1,n-1까지 도달할 수 있는 경우의 수를 구하는 문제다. 각 인덱스에 적혀있는 칸만큼 오른쪽 혹은 아래로 움직일 수 있으며, 범위 밖으로는 움직일 수 없고 칸에 적힌만큼 정확히 이동해야한다. 그래서 모든 인덱스를 순차적으로 돌면서 dp 값이 0이 아니고, 해당 인덱스가 움직일 수 있는 값이 0이 아닐 때, dp를 최신화해줬다. 경우의 수를 누적시키며 답을 찾아간다고 생각하면 된다. 처음에는 dfs로 풀려고 생각하다가, 경로의 개..
-
BOJ) 이동하기알고리즘/백준 2020. 8. 2. 00:01
이동하기 11048번: 이동하기 준규는 N×M 크기의 미로에 갇혀있다. 미로는 1×1크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여져 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다. 준규는 �� www.acmicpc.net 풀이 미로에 같힌 준규가 각 방에 놓여있는 사탕을 주워먹으면서 갈 때, 먹을 수 있는 사탕의 최대 갯수를 구하는 문제다. 이 문제는 언젠가 풀었던 것 같다. 아마 프로그래머스 문제 중 하나이지 않을까 싶다. 아무튼, dp를 이용해서 문제를 풀었다. 맵의 처음부터 x축을 순회하면서 좌측과 상단 중 사탕이 더 많은 갯수를 더해가면서 마지막 위치에 도달하게 설정했다. 이후, n, m의 dp값을 출력해서 답을 쉽게 구할 수 있었다. 코드 im..
-
BOJ) 가장 긴 감소하는 부분 수열알고리즘/백준 2020. 8. 1. 23:47
가장 긴 감소하는 부분 수열 11722번: 가장 긴 감소하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 감소하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 30, 10, 20, 20, 10} 인 경우에 가장 긴 감소하는 부분 수열은 A = {10, 30, 10, 20, 20, 10} � www.acmicpc.net 풀이 가장 긴 감소하는 부분 수열을 구하는 문제다. Longest Increasing Subsequence와 조건만 다른 Longest Decreasing Subsequence 문제다. LIS 문제의 조건을 반대로만 해주면 쉽게 풀 수 있다. 우선, int[] 배열 dp를 선언했다.그리고, 순회하는 인덱스의 다음 인덱스부터 n까지 돌면서 순회하고있는 인덱스의..
-
BOJ) 동전 2알고리즘/백준 2020. 7. 27. 23:57
동전 2 2294번: 동전 2 첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다. 가치가 같은 동전이 여러 번 주�� www.acmicpc.net 풀이 방금 전 포스팅한 LIC 문제보다 푸는데 조금 더 많은 시간이 걸렸다. 먼저, 동전 1과 다르게 k원을 만드는 최소 값을 구해야 한다는 조건이 까다롭게 느껴졌다. 또한, 만들 수 없는 경우 -1을 리턴해야한다는 부분을 간과했다. 마지막으로 고민한 부분은 점화식을 어떻게 세우는가였다. 우선 coin의 값이 뒤죽박죽일 수 있기 때문에, Arrays.sort를 통해 오름차순 정렬을 해주었다. 이후, 답이 될 dp[k]는..
-
BOJ) 가장 긴 증가하는 부분 수열 (LIS, Longest Increasing Subsequence)알고리즘/백준 2020. 7. 27. 23:51
가장 긴 증가하는 부분 수열 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이 www.acmicpc.net 풀이 어제 푼 가장 큰 증가하는 부분수열 (BIS)와 유사한 문제다. 다른 점이 있다면, 최대 값을 구하는 것이 아니라 최대 길이를 구하는 것이다. 그래서, Math.max를 통해 값을 증가 시켰던 것과 달리, Math.max를 통해 카운트를 증가시켜준다. 먼저, 자신만 존재하는 부분 수열에 대해서 dp[n]에 1을 저장한다. 이후, 탐색을 통해 자신보다 큰..
-
BOJ) 가장 큰 증가 부분 수열알고리즘/백준 2020. 7. 26. 17:33
가장 큰 증가 부분 수열 11055번: 가장 큰 증가 부분 수열 수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분 수� www.acmicpc.net 풀이 다이나믹 프로그래밍 문제는 너무 어렵다.. ㅠㅠ 다른 문제 유형보다 생각을 조금 많이 요한다. 많은 실패를 겪고 답을 찾았다. 먼저, 각 index에서 취할 수 있는 가장 큰 증가 부분 수열의 합을 저장할 dp를 선언해준다. 이후 for문을 통해 index를 탐색하면서( i ) dp[i] 에 최대값을 저장한다. 최대값을 저장하는 과정은 0부터 해당 index 전 까지 for..
-
BOJ) 합분해알고리즘/백준 2020. 7. 26. 15:48
합분해 2225번: 합분해 첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다. www.acmicpc.net 풀이 0~ N까지의 정수 K 개를 선택하여 N을 만드는 경우의 수를 구하는 문제다. 덧셈의 순서가 다르면 다른 경우로 체크한다. (1 + 2 와 2 + 1 은 다른 경우) 각각의 수는 여러번 이용 가능하며, 1,000,000,000으로 나눈 나머지를 출력해야한다. 우선 k개를 이용했을 때, 특정 숫자 n을 구할 수 있는 경우의 수를 담기 위해 2차원 배열의 dp를 선언했다. int[][] dp = new int[k][n]; 우선 k = 1 일 때, (0 ~ N까지 하나만 이용했을 때) 숫자를 만들 수 있는 경우를 1로 저장해줬다. (0이든, 1이든 ... N이든 자기 자신을 딱 하..
-
BOJ) LCS알고리즘/백준 2020. 7. 23. 15:44
LCS 9251번: LCS LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다. www.acmicpc.net 풀이 이 문제를 통해 LCS 알고리즘을 처음 학습했다. LCS(Longest Common Subsequence)는 최장 공통 부분 수열을 의미하며, 두 수열이 주어졌을 때, 부분 수열이 되는 수열 중 가장 긴 것을 찾는 것이다. 이 문제에서는 알파벳으로 이루어진 두 문장이 주어졌으므로, 두 문자열에서 알파벳의 부분 수열이 공통으로 가장 긴 길이를 찾아야 한다. 문제의 예시를 통해 LCS 이론을 살펴보면 다음과 ..