본문 바로가기

알고리즘/백준

[BOJ 5557] 1학년(메모리 초과 발생 이유)

https://www.acmicpc.net/problem/5557

 

5557번: 1학년

문제 상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀고 있다. 예를 들어, "8 3 2 4 8 7 2 4 0 8 8"에서 등식 "8+3-2-4+8-7-2-4-0+8=8"을 만들 수 있다. 상근이는 올바른 등식을 만들려고 한다. 상근이는 아직 학교에서 음수를 배우지 않았고, 20을 넘는 수는 모른다.

www.acmicpc.net

 

 

이 문제는 다이나믹 프로그래밍 문제이다.

 

 

 

 

다이나믹 프로그래밍의 본질은, 큰 문제를 작은 문제를 통해서 해결한다라는 것을 잊지말자!

 

 

 

 

i번까지의 연산의 값을, 이전에 구해놓은 연산을 통해서 구할 수 있다.

 

 

 

 

이전에 구해놓은 값들 + i번째 값

이전에 구해놓은 값들 - i번째 값

 

 

 

 

위의 관계를 점화식으로, 작성을 해야 한다. 

 

 

 

 

만약 vector를 선언하고, 거기다가 차례로 i번째까지 값을 저장해놓으면 메모리초과가 발생할 것이다.

 

 

 

 

따라서, vector라는 별도의 자료구조없이 문제를 해결해야 한다.

 

 

 

 

DP[i][j] = i번째까지 연산을 했을 때, j라는 값이 나온 횟수

 

 

 

 

라고 정의하면 문제를 해결할 수 있다.

 

 

 

 

 

해설코드(C++).

 

#include <iostream>

using namespace std;

 

int N;

long long arr[101];

long long dp[101][21];

 

int main() {

    cin >> N;

    for(int i = 1; i <= N; i++)

        cin >> arr[i];

        

    dp[1][arr[1]] = 1;

    for(int i = 2; i <= N - 1; i++){

        for(int j = 0; j <= 20; j++){

            if(dp[i - 1][j] == 0)

                continue;

                

            int val1 = j + arr[i];

            int val2 = j - arr[i];

            

            if(val1 <= 20)

                dp[i][val1] += dp[i - 1][j];

                

            if(val2 >= 0)

                dp[i][val2] += dp[i - 1][j];

        }

    }

    

    cout << dp[N - 1][arr[N]] << endl;

    return 0;

}

 

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ 2098] 외판원 순회(비트마스크, 자세한 설명)  (0) 2020.04.15
[BOJ 10164] 격자상의 경로  (0) 2020.04.12
[BOJ 10942] 팰린드롬?  (0) 2020.04.11
[BOJ 9251] LCS(왜 동적계획법인가?)  (0) 2020.04.08
9252번 : LCS 2  (0) 2020.02.03