Problem SolvingAug 31, 2025

[프로그래머스] 131129 카운트 다운 (C/C++)

[프로그래머스] 131129 카운트 다운 (C/C++)

문제

https://school.programmers.co.kr/learn/courses/30/lessons/131129



풀이

문제를 읽고 이전 상태가 다음 상태에 영향을 미치고, 관리해야하는 상태의 가지수가 많지 않다는 점에 착안하여 동적 계획법을 적용했다.



소스 코드

C++17
#include <bits/stdc++.h>

#define INF 10000

std::array<size_t, 4> operator+(const std::array<size_t, 4> &lhs, const std::array<size_t, 4> &rhs) {
    return { lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3] };
}

bool compare(const std::array<size_t, 4> &lhs, const std::array<size_t, 4> &rhs) {
    size_t sum_lhs = std::reduce(lhs.begin(), lhs.end(), 0);
    size_t sum_rhs = std::reduce(rhs.begin(), rhs.end(), 0);

    return (sum_lhs == sum_rhs)
        ? (rhs[0] + rhs[3] < lhs[0] + lhs[3])
        : (sum_lhs < sum_rhs);
}

std::vector<int> solution(int target) {
    std::vector<std::array<size_t, 4>> moves(61, { INF, INF, INF, INF });
    std::vector<std::array<size_t, 4>> dp(target + 1, { INF, INF, INF, INF });

    for (size_t i = 1; i <= 20; i++) {
        moves[i] = std::min(moves[i], { 1, 0, 0, 0 }, compare);
        moves[2 * i] = std::min(moves[2 * i], { 0, 1, 0, 0 }, compare);
        moves[3 * i] = std::min(moves[3 * i], { 0, 0, 1, 0 }, compare);
    }
    moves[50] = { 0, 0, 0, 1 };

    dp[0] = { 0, 0, 0, 0 };
    for (size_t i = 0; i < target; i++) {
        for (size_t j = 1; j <= 60 && i + j <= target; j++) {
            dp[i + j] = std::min(dp[i + j], dp[i] + moves[j], compare);
        }
    }

    return {
        std::reduce(dp[target].begin(), dp[target].end(), 0),
        static_cast<int>(dp[target][0] + dp[target][3])
    };
}

Share this post

N