포스트

16198 에너지 모으기 (C++)

백준 16198번 에너지 모으기

기초적인 DFS문제에 추가 사항들이 몇개 붙은 문제

1. 문제


간단 설명

image

예제 1번을 예로 들면, 4개의 에너지 구슬이 있다

각 에너지 구슬은 1, 2, 3, 4 의 에너지를 가지고 있음

image

첫번째로 3번째 구슬을 선택해서 제거한다면

전체 남은 구슬은 3개가 되고, W_2 * W_4 = 8 만큼의 에너지를 모을 수 있다

image

두번째로 2번째 구슬을 선택해서 제거한다

전체 남은 구슬은 2개가 되고, W_1 * W_3 = 4 만큼의 에너지를 모을 수 있다

이를 이전에 모은 에너지랑 더하면 총 12가 된다

2. 문제 분석


주의점

  • 에너지를 모으는 방법은 다음과 같으며, 반복해서 사용할 수 있다고 되어있으나,

    구슬을 제거해버리므로 의미가 없음

  • 첫 번째와 마지막 에너지 구슬은 고를 수 없다

필요변수

전체 구슬의 개수 int N (3 <= N <= 10)

구슬의 에너지 정보를 담을 벡터 vector<int> energy_ball (1 ≤ W_i ≤ 1,000)

최대값을 비교하면서 결과를 저장할 int result

최대 에너지는 10개가 1000일때, 8000000이므로, int형으로 처리 가능

알고리즘

1
2
3
4
5
6
7
8
9
10
1. N과 N개 구슬 입력받기
2. DFS 시작
    2-1. 만약 선택한 구슬의 개수가 N-2라면
    - 즉 더이상 구슬을 고를 수 없다면, 현재까지 저장된 sum 값과 이전 결과값을 비교한다 
    2-2. 첫번째와 마지막 에너지 구슬을 제외하고 골라본다
        - 현재 에너지를 계산하고, 이를 매개변수로 넘겨줌
        2-2-1. 구슬을 저장한 벡터에서 현재 에너지 구슬을 제거
        2-2-2. DFS 호출
        2-2-3. DFS가 종료되서 나왔으면 다시 기존 위치에 구슬 놓기

3. 소스코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int N;
vector<int> energy_ball;
int result = 0;

void dfs(int level, int sum) {
	if (level == N - 2) {
		result = max(result, sum);
		return;
	}
	// 첫 번째와 마지막 에너지 구슬은 고를 수 없다
	for (int i = 1; i < energy_ball.size()-1; i++) {
		int cur_energy = energy_ball[i - 1] * energy_ball[i + 1];
		
		// i번째 에너지 구슬을 제거
		int backup = energy_ball[i];
		energy_ball.erase(energy_ball.begin() + i);

		// dfs 호출
		dfs(level + 1, sum + cur_energy);

		// i번째 에너지 구슬을 다시 원상복구
		energy_ball.insert(energy_ball.begin() + i, backup);
	}

	return;
}

int main() {
	// freopen_s(new FILE*, "input.txt", "r", stdin);
	cin >> N;
	energy_ball.resize(N);
	for (int i = 0; i < N; i++) {
		cin >> energy_ball[i];
	}

	dfs(0, 0);

	cout << result << endl;

	return 0;
}

  • 벡터의 특정 위치의 원소를 제거하고 원복하는 과정이 공부가 되었다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.