※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 5351번 문제인 Coin Row이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/5351
동전 모음이 하나인 경우 그 모음을 고르면 된다. 동전 모음이 둘 이상이라고 가정해보자.
어떤 두 위치를 선택해 동전을 가져갈 때, 이 두 위치 사이에 셋 이상의 동전 모음이 있다면 둘 사이의 동전을 적어도 하나는 더 골라야 함을 관찰하자. 적어도 하나 이상의 동전 모음을 더 고를 수 있는데 안 고르면 그 경우를 최적으로 볼 수 없기때문이다. 비슷한 이유로 첫 두 동전 모음 중 적어도 하나의 동전 모음을 항상 골라야 하며, 마지막 두 동전 모음 중 적어도 하나의 동전 모음을 항상 골라야 함을 관찰하자.
따라서 두 칸 이전의 칸을 골랐었는지 여부와 세 칸 이전의 칸을 골랐었는지 여부를 기준으로 점화식을 세워 dp로 문제를 해결할 수 있다.
항상 첫 칸의 동전이나 마지막 칸의 동전을 골라야 할 필요는 없음에 유의하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <string>
using namespace std;
int N;
string s;
int A[20];
int dp[20];
void solve() {
getline(cin, s);
s += ' ';
N = 0;
int val = 0;
for (auto &l : s) {
if (l == ' ') {
A[N] = val;
N++;
val = 0;
}
else val = val * 10 + (l - '0');
}
if (N == 1) {
cout << A[0] << '\n';
return;
}
int ans = max(A[0], A[1]);
dp[0] = A[0], dp[1] = A[1];
for (int i = 2; i < N; i++) {
if (i > 2) dp[i] = max(dp[i - 2], dp[i - 3]) + A[i];
else dp[i] = dp[i - 2] + A[i];
ans = max(ans, dp[i]);
}
cout << ans << '\n';
}
int T;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> T;
getline(cin, s);
while (T--) solve();
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 11626 // C++] Physical Music (0) | 2024.07.08 |
---|---|
[BOJ 11255 // C++] ITAI Virus (0) | 2024.07.07 |
[BOJ 5081 // C++] Constellations (0) | 2024.07.05 |
[BOJ 3933 // C++] 라그랑주의 네 제곱수 정리 (0) | 2024.07.04 |
[BOJ 30510 // C++] 토마에 함수 (1) | 2024.07.03 |