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;
}