※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 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

+ Recent posts