문제링크
https://www.acmicpc.net/problem/1102
1102번: 발전소
은진이는 발전소에서 근무한다. 은진이가 회사에서 잠깐 잘 때마다, 몇몇 발전소가 고장이난다. 게다가, 지금 은진이의 보스 형택이가 은진이의 사무실로 걸어오고 있다. 만약 은진이가 형택이
www.acmicpc.net
풀이
- DP using Bitfields
- 켜져있는 발전소 상태를 비트필드로 나타낸다.
- 지금 상태에서 한 발전소 키기 = min(켜져있는 발전소에서 꺼져있는 발전소 키기)
코드
#include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N;
cin >> N;
vector<vector<int> > cost(N, vector<int> (N));
for (auto& e: cost) for (auto& ee: e) cin >> ee;
string s;
cin >> s;
int num = 0;
int tmp = 1;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == 'Y') {
num |= tmp;
}
tmp <<= 1;
}
int P; cin >> P;
int ans = 1e9;
vector<int> dp(1 << s.size(), 1e9);
dp[num] = 0;
queue<pair<int, int> > q;
q.push({num, dp[num]});
auto countOnes = [&](int n) {
int ones = 0;
while (n) {
if (n & 1) ones++;
n >>=1;
}
return ones;
};
while (q.size()) {
auto [f, d] = q.front();
q.pop();
if (dp[f] < d) continue;
if (countOnes(f) >= P) {
ans = min(ans, d);
continue;
}
for (int i = 0; i < s.size(); ++i) {
if ((f & (1 << i)) == 0) {
int nn = f | (1 << i);
int flag = false;
for (int j = 0; j < s.size(); ++j) {
if ((f & (1 << j))) {
if (dp[nn] > d + cost[j][i]) {
dp[nn] = d + cost[j][i];
flag = true;
}
}
}
if (flag) q.push({nn, dp[nn]});
}
}
}
if (ans == 1e9) {
cout << "-1\n";
} else {
cout << ans << '\n';
}
}
728x90
'PS > BOJ' 카테고리의 다른 글
백준 22581번: IkaNumber (0) | 2022.07.12 |
---|---|
백준 1557번: 제곱 ㄴㄴ (0) | 2022.07.05 |
백준 2011번: 암호코드 (0) | 2022.07.02 |
백준 13546번: 수열과 쿼리 4 (0) | 2022.03.08 |
백준 6171번: 땅따먹기 (0) | 2022.03.08 |