본문 바로가기

알고리즘/백준

백준 2629 양팔 저울

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

 

2629번: 양팔저울

첫째 줄에는 추의 개수가 자연수로 주어진다. 추의 개수는 30 이하이다. 둘째 줄에는 추의 무게들이 자연수로 가벼운 것부터 차례로 주어진다. 같은 무게의 추가 여러 개 있을 수도 있다. 추의 무

www.acmicpc.net

백 트랙킹과 DP를 활용하는 문제다.

 

적은 N과 상대적으로 널럴한 시간 제한을 보자마자 백트랙킹 감이 오긴했으나... 아직 recursion 알고리즘을 짜는 게 미흡한 것 같다.

 

이렇게 ''완전탐색''을 하면 반드시 풀 수 있는 문제를 백트랙킹과 DP로 구현할때는

 

각 케이스에서 발생 가능한 모든 사례를 Recursion으로 처리하는 연습을 해야겠다.

ㅠㅠ

 

/* 양팔 저울 */

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

using namespace std;

int n_of_sinker, n_of_ball;
int sinker[30], s_of_sinker[30 + 1][40000 + 1];

/* 두 개를 더하거나, 두 개를 빼거나, 하나를 반대쪽에 놔두기 */
/* 일단 케이스를 생각해보는거야! */

void recursive(int cur, int hab) {
	if (cur > n_of_sinker) return;
	if (s_of_sinker[cur][hab] == true) return;

	s_of_sinker[cur][hab] = true;

	// 두 개를 더하기
	recursive(cur + 1, hab + sinker[cur]);
	recursive(cur + 1, hab);
	recursive(cur + 1, abs(hab - sinker[cur]));
}


int main(void) {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	/* Input */
	cin >> n_of_sinker;
	for (int i = 0; i < n_of_sinker; cin >> sinker[i++]);

	recursive(0, 0);

	cin >> n_of_ball;
	for (int i = 0; i < n_of_ball; i++) {
		int target; cin >> target;
		int j;
		for (j = 0; j <= n_of_sinker; j++) {
			if (s_of_sinker[j][target] == true) break;
		}

		if (j > n_of_sinker) cout << "N ";
		else cout << "Y ";
	}

	return 0;
}

'알고리즘 > 백준' 카테고리의 다른 글

백준 15684 사다리 조작  (0) 2020.08.13
백준 1981 배열에서 이동  (0) 2020.08.13
백준 1613 역사  (0) 2020.08.12
백준 5427 불  (0) 2020.08.10
백준 17144 미세먼지 안녕!  (0) 2020.08.10