[ 백준 ] 5721 / 사탕 줍기 대회

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
62/228
post-thumbnail

# Appreciation

/*
 * Problem :: 5721 / 사탕 줍기 대회
 *
 * Kind :: Dynamic Programming
 *
 * Insight
 * - 박스를 고른 칸의
 *   위쪽 행, 아래쪽 행,
 *   왼쪽 칸, 오른쪽 칸
 *   의 사탕이 모두 사라진다
 *   + 흠... 규칙이 너무 복잡한데...
 *     일단 고른 칸에 해당하는 행에서 가져갈 수 있는 사탕의 최대 개수는 알 수 있다
 *     행을 기준으로 DP 를 적용하면 되니까
 *     # 잠깐만! 그럼 각 행에서 가져갈 수 있는 최대 개수를 저장한 배열을 구할 수 있다면
 *       그 배열에서 DP 를 또 적용하면 되겠네...?
 *       -> 왼쪽 칸, 오른쪽 칸 => 행 DP
 *          위쪽 행, 아래쪽 행 => 열 DP
 *          를 뜻하는 것이었군!!!
 *
 * Point
 * - 1 <= M x N <= 10^5
 *   이므로 사탕의 최대개수는 10^8 이 넘지 않아
 *   int 자료형으로 충분히 계산할 수 있다
 *   + 1 <= M, N <= 10^5
 *     였다면 long 을 써야했겠지
 */

# Code

//
//  Codeforces
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

#define endl '\n'

// Set up : Global Variables
/* None */

// Set up : Functions Declaration
int DP(vector<int> A);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    while (true) {
        int M, N;
        cin >> M >> N;
        if (M == 0 && N == 0) break;

        vector<int> B[M];
        for (int i=0; i<M; i++) {
            B[i].resize(N);
            for (int j=0; j<N; j++) {
                cin >> B[i][j];
            }
        }

        // Process
        vector<int> R(M);
        for (int i=0; i<M; i++) {
            R[i] = DP(B[i]); /* 행 기준 DP */
        } int ans = DP(R); /* 열 기준 DP */

        // Control : Output
        cout << ans << endl;
    }
}

// Helper Functions
int DP(vector<int> A)
/* 배열 A 에서 가져갈 수 있는 최대 사탕의 개수를 반환 */
{
    int L = A.size();
    if (L == 1) return A[0];

    int dp[L];
    memset(dp, 0, sizeof(dp));
    dp[0] = A[0];
    dp[1] = max(A[0], A[1]);
    for (int i=2; i<L; i++) {
        dp[i] = max(dp[i-1], A[i]+dp[i-2]);
    }

    return dp[L-1];
}
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글