반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Archives
Today
Total
관리 메뉴

코딩하기 좋은날

백준 1102 발전소 본문

백준(Baekjoon) 문제

백준 1102 발전소

huiung 2020. 1. 19. 12:27
반응형

dp 문제입니다. 16개 이하의 발전소가 있을 때 이발전소를 주어진 P개를 켜야 하는 문제인데 발전소의

켜짐 꺼짐 유무를 확인하기 위해 비트마스킹을 이용하여 해결을 하여야 합니다.

2^16만큼 잡아서 dp[70000] 정도로 잡아주면 되겠습니다.

 

이때 발전소를 키기 위해서는 켜진 발전소를 이용하여 꺼진 발전소를 키므로 각 함수에서

꺼진 발전소를 찾고 얘를 켤수 있는 발전소를 찾아서 재귀를 돌면 됩니다. 이때 cost가 0인것은 진짜로 0인 것이지 킬 수 없는게 아니라는 점(처음에 못키는줄 알았습니다.) 생각하면서 해결하면 됩니다. 외판원 순회문제와 유사한데 좀더 간단한(?) 문제 같습니다.

 

다음은 코드입니다.

 

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>

#define INF 987654321
using namespace std;

int cost[17][17];
int dp[100000]; //cur발전기 기준 visited 발전기들 켜짐
int P;
int N;

int sol(int visited, int cnt) {
	
	if (P == cnt) {
		return 0;
	}

	int& ret = dp[visited];
	if (ret != -1) return ret;
	ret = INF;

	for (int j = 0; j < N; j++) {
		if (!((1 << j) & visited)) { //꺼진 발전소 찾고 킬 발전소 아래에서
			for (int i = 0; i < N; i++) {
				if (i == j) continue;

				if (((1 << i) & visited)) { //발전소가 켜져있다면
					ret = min(ret, sol(visited | (1 << j), cnt + 1) + cost[i][j]);
				}

			}
		}
	}
	return ret;
}

int main(void) {
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	memset(dp, -1, sizeof(dp));
	cin >> N;

	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			cin >> cost[i][j];

	int visited = 0;
	string str; cin >> str;
	cin >> P;

	for (int i = 0; i < str.size(); i++) {
		if (str[i] == 'Y') {
			P--;
			visited |= (1 << i);
		}
	}
	
	if (P <= 0) {
		cout << 0;
		return 0;
	}

	int ans = sol(visited, 0);
	if (ans == INF) cout << -1;
	else cout << ans;
	return 0;
}
반응형

'백준(Baekjoon) 문제' 카테고리의 다른 글

백준 2343 Dance Dance Revolution  (0) 2020.01.19
백준 7578 공장  (0) 2020.01.19
백준 2618 경찰차  (2) 2020.01.19
백준 파이프 옮기기 2  (0) 2019.11.10
백준 17135 캐슬 디펜스  (0) 2019.11.10