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

 

이번에 볼 문제는 백준 5721번 문제인 사탕 줍기 대회이다.
문제는 아래 링크를 확인하자.

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

 

5721번: 사탕 줍기 대회

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 M과 N이 주어졌다. (1 ≤ M × N ≤ 105) 다음 M개 줄에는 박스에 들어있는 사탕의 개수 N개가 주어진다. 박스에 들

www.acmicpc.net

문제의 조건을 잘 생각해보면, 하나의 행에서 어떤 사탕을 고른다면 그 행에서 서로 인접하는 칸이 없도록 칸을 골라 최대 개수의 사탕을 주울 수 있다는 점을 알 수 있다.

 

각 행별로 주울 수 있는 최대 개수를 고른다면, 행단위로 "고를 행과 안 고를 행"을 선택하는 것으로 최대로 주울 수 있는 사탕의 개수를 알 수 있다. 방식은 한 행에서 주울 수 있는 최대 사탕의 개수를 구하는 것과 완전히 같다.

 

가능한 행, 열의 개수의 최댓값이 각각 10만이므로 10만 by 10만 크기의 배열을 선언하는 것은 무리이다.

필요한 만큼만 선언하고 계산하는 방식으로 구현하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int cols[100000];
int rows[100000];
int dp[100000];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int R, C; cin >> R >> C;
	while (R > 0) {
		for (int r = 0; r < R; r++) {
			for (int c = 0; c < C; c++) cin >> cols[c];
			if (C == 1) {
				rows[r] = cols[0];
				continue;
			}
			dp[0] = cols[0], dp[1] = max(cols[0], cols[1]);
			for (int i = 2; i < C; i++) {
				dp[i] = max(dp[i - 1], dp[i - 2] + cols[i]);
			}
			rows[r] = dp[C - 1];
		}
	
		if (R == 1) cout << rows[0] << '\n';
		else {
			dp[0] = rows[0], dp[1] = max(rows[0], rows[1]);
			for (int i = 2; i < R; i++) {
				dp[i] = max(dp[i - 1], dp[i - 2] + rows[i]);
			}
			cout << dp[R - 1] << '\n';
		}

		cin >> R >> C;
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1017 // C++] 소수 쌍  (0) 2021.09.23
[BOJ 10282 // C++] 해킹  (0) 2021.09.22
[BOJ 22865 // C++] 가장 먼 곳  (0) 2021.09.20
[BOJ 1058 // C++] 친구  (0) 2021.09.19
[BOJ 2661 // C++] 좋은수열  (0) 2021.09.18

+ Recent posts