Problem SolvingAug 31, 2025
[프로그래머스] 131129 카운트 다운 (C/C++)
![[프로그래머스] 131129 카운트 다운 (C/C++)](/assets/posts/01k3z28qg8pz3a1cgd40db1k8t/index.png)
문제
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])
};
}