본문 바로가기

Algorithm/DP(Dynamic Programing)

(64)
(C++) - 프로그래머스(연습문제) : 멀리 뛰기 https://programmers.co.kr/learn/courses/30/lessons/12914 코딩테스트 연습 - 멀리 뛰기 효진이는 멀리 뛰기를 연습하고 있습니다. 효진이는 한번에 1칸, 또는 2칸을 뛸 수 있습니다. 칸이 총 4개 있을 때, 효진이는 (1칸, 1칸, 1칸, 1칸) (1칸, 2칸, 1칸) (1칸, 1칸, 2칸) (2칸, 1칸, 1칸) (2칸, 2 programmers.co.kr dp문제였습니다. 풀이방법 1칸 또는 2칸을 뛰므로 n에 도착하기 위한 경우의 수 점화식은 다음과 같습니다. D[n] = D[n-1] + D[n-2] Code #include #define MOD 1234567 using namespace std; using ll = long long; ll d[2001]..
(C++) - 백준(BOJ) 2096번 : 내려가기 www.acmicpc.net/problem/2096 2096번: 내려가기 첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다. www.acmicpc.net dp문제였습니다. 풀이방법 메모리 제한이 4mb이므로 400만 byte크기 이하의 변수들을 선언해 사용해야 합니다. 이 문제는 10만개의 배열 이상 사용하지 않아도 되는 문제입니다. 1. 첫 번쨰 행의 세 수를 먼저 입력 받습니다. 그 후 d, d2배열에 각각 저장합니다. 2. 현재 열이 0번째 열이면 이전의 행에서는 0,1번째 열 중 최대값에서 현재 열의 값을 더한값이 현재 열이 가질 수 있는 최댓값입니다. 현재 열이 1번..
(C++) - 백준(BOJ) 15988번 : 1, 2, 3 더하기 3 www.acmicpc.net/problem/15988 15988번: 1, 2, 3 더하기 3 각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다. www.acmicpc.net dp문제였습니다. 풀이방법 * 답이 나올 수 있는 범위를 조심해야합니다. int범위를 초과할 수 있으므로 long long으로 변수를 선언해줘야합니다. * 테스트 케이스로 인해 출력이 많아지므로 c와 동기화를 끊어 입출력이 빨라지도록 합니다. * Modular 연산을 주의해야합니다. 덧셈에 대해 분배법칙이 성립하나 더할 때 마다 범위가 초과할 수 있으므로 매번 더할 때 마다 Modular 연산을 해줘야 합니다. i를 만드는 경우의 수는 i-1을 만드는 경우의 수..
(C++) - 백준(BOJ) 2225번 : 합분해 www.acmicpc.net/problem/2225 2225번: 합분해 첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다. www.acmicpc.net dp로 푼 문제였습니다. 풀이방법 * 200까지의 수를 200개까지 뽑을 수 있기 때문에 순열로 접근하시면 시간초과를 맛볼 수 있습니다. 1. k개로 n을 만드는 경우의 수를 저장할 d배열을 선언해줍니다. 2. k-1개로 n-x수를 만드는 경우의 수들을 모두 더한다면 마지막으로 x를 사용했을 때 n을 만들 수 있습니다. 따라서 점화식을 세우면 다음과 같습니다. d[i][j] = sum(d[i-1][0 ~ j ~ n]) Code #include #define MOD 1'000'000'000 #define ll long long using ..
(C++) - 백준(BOJ) 21318번 : 피아노 체조 www.acmicpc.net/problem/21318 21318번: 피아노 체조 피아노를 사랑하는 시은이는 매일 아침 피아노 체조를 한다. 시은이는 N개의 악보를 가지고 있으며, 1번부터 N번까지의 번호로 부른다. 각 악보는 1 이상 109 이하의 정수로 표현되는 난이도를 www.acmicpc.net 부분합 문제였습니다. 풀이방법 1. 악보 1부터 실수를 할 때마다 배열 d의 i+1번에 실수횟수를 1더해서 저장해줍니다. 2. d[end] - d[start]시 해당 구간 사이의 실수횟수를 구할 수 있습니다. Code #include #define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; int n, ..
LCS(Longest Common Subsequence) 최장 공통 부분 문자열입니다. 부분이라는 뜻은 연속하지 않아도 된다는 뜻입니다. 이 문제는 두 문자열이 겹치는 문자들의 최장 길이를 구하는 문제입니다. 띄엄띄엄 겹치더라도 이들을 모아 각각 하나의 문자열을 만들었을 때 두 문자열이 같다면 공통 부분 문자열이고 이 문자열의 길이가 곧 LCS에서 구하는 답 입니다. www.acmicpc.net/problem/9251 9251번: LCS LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다. www.acmicpc.net 대표적인 백준 문제를 예시로 이해해 봅시다. 나와 있는 ..
(C++) - 백준(BOJ) 2565번 : 전깃줄 www.acmicpc.net/problem/2565 2565번: 전깃줄 첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결되는 www.acmicpc.net dp(lis) 문제였습니다. 풀이방법 1. a, b가 pair형태로 저장되는 vector v변수를 선언 후 n개의 젓깃줄 정보를 입력받습니다. 2. a를 기준으로 sort해줍니다. 3. 교차하지 않으려면 봐야할 정보는 1가지 입니다. 이미 a는 오름차순으로 정렬되어 있으니 b만 연속해서 오름차순으로 되어 있는지, 그 길이는 몇인지 확인하면 됩니다. 4. n - 길이가 답이고 이를 출력합니다. Code #include ..
(C++) - 백준(BOJ) 9184번 : 신나는 함수 실행 www.acmicpc.net/problem/9184 9184번: 신나는 함수 실행 입력은 세 정수 a, b, c로 이루어져 있으며, 한 줄에 하나씩 주어진다. 입력의 마지막은 -1 -1 -1로 나타내며, 세 정수가 모두 -1인 경우는 입력의 마지막을 제외하면 없다. www.acmicpc.net 메모이제이션으로 불필요한 함수 호출을 막는 dp문제였습니다. 풀이방법 1. w라는 함수를 실행하기 전에 d[a+50][b+50][c+50]값이 저장되어 있는지 확인하는 ret 참조변수를 선언 후 저장합니다. a,b,c값이 음수를 포함하므로 음수 인덱스에 접근하지 않도록 오른쪽으로 50만큼 당겨주어 저장했기 때문에 읽을 때 +50한만큼 인덱스를 가져옵니다. 2. w함수를 수행한 결과를 포맷에 맞게 출력합니다. Cod..