본문 바로가기
Algorithm/BOJ

[BOJ] 16198번: 에너지 모으기 (c++)

by HBGB 2020. 6. 11.

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

 

16198번: 에너지 모으기

N개의 에너지 구슬이 일렬로 놓여져 있고, 에너지 구슬을 이용해서 에너지를 모으려고 한다. i번째 에너지 구슬의 무게는 Wi이고, 에너지를 모으는 방법은 다음과 같으며, 반복해서 사용할 수 있�

www.acmicpc.net

 

N - 1길이의 새로운 구슬벡터를 만들어서 재귀함수 호출

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int max_sum;

void go(vector<int>& nrg, int sum)
{
	// 구슬이 2개만 남으면 최대합계 갱신 후 종료
	int N = nrg.size();
	if (N == 2)
	{
		max_sum = max(sum, max_sum);
		return;
	}

	// new_nrg에 i번째를 제외한 나머지 구슬 값 넣기
	vector<int> new_nrg(N - 1);
	for (int i = 1; i < N - 1; ++i)
	{
		int idx = 0;
		for (int j = 0; j < N; ++j)
		{
			if (j == i)
			{
				continue;
			}
			new_nrg[idx++] = nrg[j];
		}

		// 새로운 구슬벡터와 sum + nrg[i - 1] * nrg[i + 1]값으로 재귀함수 호출
		go(new_nrg, sum + nrg[i - 1] * nrg[i + 1]);
	}
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	// 입력
	int N;
	cin >> N;
	vector<int> nrg(N);
	for (int i = 0; i < N; ++i)
	{
		cin >> nrg[i];
	}

	/*
		구슬이 2개 남을때까지 x번째 구슬을 지우면서 
		x - 1번째 * x + 1번째 값의 합계를 구하는 재귀함수
	*/
	go(nrg, 0);

	// 출력
	cout << max_sum;

	return 0;
}

 

 

구슬의 개수 N이 3 ≤ N ≤ 10으로 작게 주어졌기 때문에 

문제의 지시사항을 충실하게 구현해보았다. 

 

 

다음과 같이 bool 벡터를 하나 만들어서 백트랙킹으로 풀이할 수도 있다. 

void go(vector<int> & nrg, vector<bool> & remove, int sum, int depth)
{
	int N = nrg.size();
	if (N == 2)
	{
		max_sum = max(sum, max_sum);
		return;
	}

	for (int i = 1; i < N - 1; ++i)
	{
		if (!remove[i])
		{
			int left = i - 1;
			int right = i + 1;
			while (remove[left])
			{
				--left;
			}
			while (remove[right])
			{
				++right;
			}

			remove[i] = true;
			go(nrg, remove, sum + nrg[left] * nrg[right], depth + 1);
			remove[i] = false;
		}
	}
}

 

 

 

'Algorithm > BOJ' 카테고리의 다른 글

[BOJ]2580번: 스도쿠 (c++)  (0) 2020.06.11
[BOJ]9663번: N-Queen (c++)  (0) 2020.06.11
[BOJ]16197번: 두 동전 (c++)  (0) 2020.06.10
[BOJ]15658번: 연산자 끼워넣기 (2) (c++)  (0) 2020.06.10
[BOJ]14225번: 부분수열의 합 (c++)  (0) 2020.06.10

댓글