Problem Solving/BOJ(백준)

[BOJ]백준 16198번: 에너지 모으기

이진2 2019. 6. 24. 23:46

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

 

16198번: 에너지 모으기

N개의 에너지 구슬이 일렬로 놓여져 있고, 에너지 구슬을 이용해서 에너지를 모으려고 한다. i번째 에너지 구슬의 무게는 Wi이고, 에너지를 모으는 방법은 다음과 같으며, 반복해서 사용할 수 있다. 에너지 구슬 하나를 고른다. 고른 에너지 구슬의 번호를 x라고 한다. 단, 첫 번째와 마지막 에너지 구슬은 고를 수 없다. x번째 에너지 구슬을 제거한다. Wx-1 × Wx+1의 에너지를 모을 수 있다. N을 1 감소시키고, 에너지 구슬을 1번부터 N번까지로 다

www.acmicpc.net

난이도 쉬운 백트래킹 문제이다

백트래킹 문제의 특성은 주로 두 가지인데

① 조합&완탐을 이용한다 ② 재귀함수를 이용하여 함수 호출 전과 후에 체크 배열 값을 바꾼다

 

이 문제에서는 두 가지가 직관적으로 보이기 때문에 쉽게 문제를 풀 수 있었다

재귀함수의 인자로 현재까지의 sum값 + 직전에너지*다음에너지 를 보내주고, depth가 최대일 때 최대값을 갱신해주면 끝!

#include <cstdio>
#include <algorithm>
using namespace std;
int n, w[1001], ans;
bool chk[1001];
void func(int x, int dep) {
	if (dep == n - 2) {
		ans = x > ans ? x : ans;
		return;
	}
	for (int i = 1, p, r; i < n - 1; i++) {
		if (!chk[i])continue;
		p = i - 1; r = i + 1;
		chk[i] = 0;
		while (!chk[p])p--; while (!chk[r])r++;
		func(x + w[p] * w[r], dep + 1);
		chk[i] = 1;
	}
}
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++)scanf("%d", &w[i]);
	fill(chk, chk + n, true);
	func(0, 0);
	printf("%d", ans);
	return 0;
}