Doby's Lab

[알고리즘] 백준 9465번: 스티커 (C++), 논리와 직관 그 어디쯤 사이에 본문

PS/BOJ

[알고리즘] 백준 9465번: 스티커 (C++), 논리와 직관 그 어디쯤 사이에

도비(Doby) 2021. 11. 18. 10:18

https://www.acmicpc.net/problem/9465

 

9465번: 스티커

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의

www.acmicpc.net

이번 문제는 TC를 보고 나서 점화식을 어떻게 짜야할지 혼란을 가져다주는 문제였다.

하지만, TC를 간단하게 생각해보면 쉽게 풀 수 있었다.


솔루션에 도달하는 과정

5
50 10 100 20 40
30 50 70 10 60

다음 TC가 문제를 다시 생각해보게 했었다. 그 전의 코드는 이렇다.

#include <iostream>
#include <cmath>
using namespace std;

int T;
int cache[2][100001] = { 0, };
int map[2][100001] = { 0, };

int main() {
	cin >> T;
	for (int t = 0; t < T; t++) {
		int n;
		cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> map[0][i];
		}
		for (int i = 1; i <= n; i++) {
			cin >> map[1][i];
		}

		for (int i = 1; i <= n; i++) {
			cache[0][i] = cache[1][i - 1] + map[0][i];
			cache[1][i] = cache[0][i - 1] + map[1][i];
		}

		cout << max(cache[0][n], cache[1][n]) << '\n';
	}
	return 0;
}

무조건 대각선 방향의 스티커를 더해주는 것이 정답이겠거니 했지만 올린 TC 같은 경우엔 한 칸 더 뒤에 있는 대각선을 택하게 된다.


솔루션에 도달하는 과정 (2)

value와 value2 중에 더 큰 값을 선택하면 된다.

그렇다면 여기서 이런 말이 나올 수 있다. '3칸 뒤의 값도 더 큰 값을 가지고 있을 수 있는데 왜 안 따지는가?'

그에 대한 답은 3칸 뒤에 값을 따질 필요 없이 value를 거쳐 대각선 2개를 더 거치면 value3에 도달할 수 있고, 값 2개를 더 더했으므로 더 큰 값을 초래하기 때문이라는 이유가 답이 된다.

 

그래서 점화식에서는 두 칸 전의 값까지만 따져주면서 점화식을 도출해내면 된다.


[AC 코드]

#include <iostream>
#include <cmath>
using namespace std;

int T;
int cache[2][100001] = { 0, };
int map[2][100001] = { 0, };

int main() {
	cin >> T;
	for (int t = 0; t < T; t++) {
		int n;
		cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> map[0][i];
		}
		for (int i = 1; i <= n; i++) {
			cin >> map[1][i];
		}

		for (int i = 1; i <= n; i++) {
			cache[0][i] = max(cache[1][i - 1], cache[1][i - 2]) + map[0][i];
			cache[1][i] = max(cache[0][i - 1], cache[0][i - 2]) + map[1][i];
		}

		cout << max(cache[0][n], cache[1][n]) << '\n';
	}
	return 0;
}
728x90