본문 바로가기

알고리즘!/Dynamic Programming33

[C] 12865: 평범한 배낭 Knapsack Problem은 학교 알고리즘 시간에 배웠어서 어떻게 해야하는지는 알고 있었는데.. 푸는데 한시간 넘게 풀었다. 그에 대한 교훈이 뭐였냐..! 첫째, 웬만해서 전역변수로 배열을 초기화하자.. 배열의 범위만 넘어가지 않는 선에서 (약 2억) 가장 쉽고 따로 초기화 해주지 않아도 되된다. 둘째, 배열의 인덱스를 정할때 0부터 시작할지 혹은 1부터 시작할지를 확실히 정하고 시작하자. 셋째, 이차원배열도 효과적이지만 그냥 배열 2개를 따로 정하는게 헷갈리지 않는 경우가 있다. 이 문제도 점화식을 구하고, for문을 이용해서 작은문제들을 풀어 결국 결과까지 도출해내는 Bottom-Up방식을 사용했다. 밑에는 소스코드다.. #include int backpack[2][102]; int dp[102].. 2023. 7. 22.
[C] 11053: 가장 긴 증가하는 부분 수열 https://www.acmicpc.net/problem/11053 11053번: 가장 긴 증가하는 부분 수열 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이 www.acmicpc.net DP 문제 풀이 정리! Dynamic Programming 문제를 풀기 위한 생각을 잠시 정리해보면... 첫째, 배열을 이용하여 배열에 저장하며 문제를 풀어야하고 둘째, 점화식들을 이용해 작은 subproblems를 이용해 반복을 통하여 문제를 풀어야한다. 셋째, 만약 수학적으로 하나의 식이 만들어지지 않는다면 조건문을.. 2023. 7. 22.
[C] 2579: 계단 오르기 이 문제도 역시 배열에 저장을 해가며 점화식을 구하기 위해 노력하였다. 먼저 각 계단마다 점수를 저장하는 score배열을 정의하고 각 단계마다 가장 높은 점수를 저장하는 arr배열을 정의하였다. 그리고 초기, 계단을 2개 오르기까지의 경우는 for문이 아닌 직접 배열에 저장하는 방식을 택했고 (어떤 방법으로 for문을 구성할지 감을 잡기위해서 & 초기값은 직접 정해줘야함) for문에서는 연속된 3개가 되는지에 따라 if문을, 그리고 각각의 if문에서 2계단을 뛰어넘는게 이득인지 1계단을 뛰어넘는게 이득인지 판별해 arr배열에 저장하였다. 그리고 이때 이차원 배열을 이용한 이유는 연속된 3개의 계단을 오른지 판별하기 위해서였다. 소스코드는 아래와 같다. #include int main(void) { int.. 2023. 7. 22.
[C] 9095: 1, 2, 3 더하기 이 문제 역시 Dynamic Programming을 이용한 문제이다. Dynamic Programming의 특징은 첫째로 문제를 작게 나누어 최대한 연산을 반복하지 않도록 하는 것이고 둘째로는 배열에 값을 저장하여 점화식을 이용하여 푸는 문제가 많은 것이다. 이 문제 역시 점화식만 잘 알 수 있었다면 쉽게 풀 수 있다. 예를 들어 4의 경우 4=1+3, 2+2, 1+3 이런식으로 표현할 수 있는데 1+3은 1+cpy[3], 2+2=2+cpy[2], 1+3=cpy[3] 으로 생각하면 4를 1,2,3으로 표현하는 모든 경우의 수를 표현할 수 있다. 이를 일반화 하면 cpy[i]=cpy[i-1]+cpy[i-2]+cpy[i-3]으로 표현할 수 있고 max를 구한 이유는 물론 이 문제는 10까지만 표현하면 되므로.. 2023. 7. 21.