본문 바로가기

Algorithm/DP(Dynamic Programing)

(65)
(C++) - 프로그래머스(Summer/Winter Coding(~2018)) : 스티커 모으기(2) https://programmers.co.kr/learn/courses/30/lessons/12971 코딩테스트 연습 - 스티커 모으기(2) N개의 스티커가 원형으로 연결되어 있습니다. 다음 그림은 N = 8인 경우의 예시입니다. 원형으로 연결된 스티커에서 몇 장의 스티커를 뜯어내어 뜯어낸 스티커에 적힌 숫자의 합이 최대가 되도록 programmers.co.kr dp문제였습니다. 풀이방법 greedy하게 띄엄띄엄 최대한으로 스티커를 떼어나면 최대일 것 같으나 그렇지 않습니다. 특정한 스티커가 점수가 나머지보다 월등히 높은 경우 그 스티커를 무조건 1개씩 건너뛰면서 떼어낼 경우 그 스티커를 떼지 못할 수 있습니다. 따라서 dp를 사용해야 합니다. 1. sticker의 size가 1인경우엔 바로 점수를 반환..
(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 ..