일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 이분탐색
- lis
- 플로이드와샬
- 이분매칭
- 수학
- DisjointSet
- DP
- 브루트포스
- 누적합
- 이진탐색
- MST
- 삼분탐색
- 투포인터
- boj
- 정렬
- dfs
- 에라토스테네스의 체
- 백준
- 그리디
- LazyPropagation
- 비트마스크
- BFS
- 위상정렬
- 구현
- 좌표압축
- 다익스트라
- 크루스칼
- lca
- 세그먼트트리
- 펜윅트리
Archives
- Today
- Total
lastknight00
[백준] 발전소(1102) 본문
문제 링크 : [백준] 발전소(1102)
문제 설명
발전소의 갯수와 발전소끼리 재시작하는 비용이 인접행렬로 주어지고,
각 발전소가 정상동작중인지 상태가 주어집니다.
마지막으로 최소한 동작해야하는 발전소의 갯수가 주어진다면,
인접행렬의 비용들을 이용하여 최소한 동작해야하는 발전소 갯수 이상의 발전소를 동작시키기 위한 최소 비용을 구하세요.
최소 비용을 구할 수 없으면 -1을 출력합니다.
입력
N(발전소의 수, 1 <= N <= 16)
Vij(i번째 발전소가 j번째 발전소를 재시작하는데 필요한 비용, 0 <= Vij <= 50)
S(발전소의 상태, Y는 가동중, N은 고장)
P(최소한 동작해야하는 발전소의 수, 0 <= P <= N)
3
0 10 11
10 0 12
12 13 0
YNN
3
출력
21
카테고리
#DP #비트마스크
시간 복잡도 상한
O(N!)만 아니면 될 것 같습니다.
해결 방법
- -1을 출력하는 경우에 대해서 먼저 생각해봅니다.
1-1. 모든 발전소가 고장난 상태에서 1개 이상의 발전소를 켜야하는 경우는 불가능한 경우입니다. - N이 작고, 각각의 상태가 0과 1로 나타낼 수 있으며, 그 상태들의 변화에 대한 내용들이므로 비트마스크를 고민해볼 수 있습니다.
- 각 발전소의 상태를 한개의 비트로 표시할 수 있으며, 16bit, 즉 64000개 내의 상태로 표시할 수 있습니다.
- 처음 주어진 상태에서 하나씩 발전소를 켜는 행위를 재귀로 반복하여 합니다.(모든 출발점에서 모든 도착점까지)
4-1. 반복하면서, 기존에 켜져있던 발전소이면 continue
4-2. 출발 발전소가 꺼져있는 상태라면 continue
4-3. 다음 발전소 하나를 켰을 때 중 최소 값을 구합니다. - 4의 조건들을 가지고 재귀를 반복하며 켜진 발전소가 P개가 될때까지 반복합니다.
시간복잡도
O(2n * n * n)
코드
#include<cstdio>
#include<algorithm>
int n,m,k,d[16][16],e[1024*64],v[1024*64],i,j;
char s[17];
int r(int s){
int x=0;
for(int i=0;i<n;i++)x+=!!(s&(1<<i));
if(x>=m)return 0;
if(v[s])return e[s];
v[s]=1;
e[s]=99999;
for(int i=0;i<n;i++){
if(!(s&(1<<i))){
for(int j=0;j<n;j++){
if(i==j)continue;
if(s&1<<j)e[s]=std::min(e[s],d[j][i]+r(s|1<<i));
}
}
}
return e[s];
}
int main(){
scanf("%d",&n);
for(i=0;i<n;i++)for(j=0;j<n;j++)scanf("%d",d[i]+j);
scanf("%s%d",s,&m);
for(i=0;s[i];i++)k|=((s[i]=='Y')<<i);
if(!m)printf("0");
else printf("%d",k==0||n<m?-1:r(k));
}
'PS' 카테고리의 다른 글
[백준] 열쇠(9328) (0) | 2020.06.24 |
---|---|
[백준] 2048(Easy)(12100) (0) | 2020.06.24 |
[백준] 기타 레슨(2343) (0) | 2020.06.09 |
[백준] 교차개수세기(1615) (0) | 2020.06.09 |
[백준] 트리(1068) (0) | 2020.06.09 |
Comments