Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- mathematics
- Eulerian path
- Euler path
- Algospot
- disjoint-set
- Eulerian circuit
- DynamicProgramming
- Segment Tree
- flows
- 백준
- Dag
- Shortest path
- scc
- dynamic programming
- hashing
- graph
- BFSDFS
- backtracking
- Sieve_of_Eratosthenes
- CS Academy
- GCD
- POJ
- graph modeling
- Cycle detecting
- Euler circuit
- BST
- BOJ
- bitmask
- implementation
- Greedy
Archives
- Today
- Total
그냥 하는 노트와 메모장
BOJ 12861 죄수에게 주는 뇌물 본문
BOJ 12861 죄수에게 주는 뇌물
[분류 : 다이나믹 프로그래밍]
[풀이]
[첫번째] 가장 처음에 Q[i]번째 죄수를 석방했다고 해보자. 그러면 1번째 죄수부터 Q[i]-1번째 죄수까지, Q[i]+1번째 죄수부터 P번째 죄수까지 모두 뇌물을 줘야한다.
[그 이후의 석방] 이제 죄수를 고를 때 Q명의 죄수 중 i번째를 석방시켰으니, 이젠 구간을 나눠서 봐야한다.
- 구간 [1, Q[i]-1]에서 Q명의 죄수 중 누굴 석방할 것인지
- 구간 [Q[i] + 1, P]에서 Q명의 죄수 중 누굴 석방할 것인지
[간단한 dp 아닌가 ?] 그러면 두 구간을 모두 다룰 수 있도록 구간 [l, r]에 대해 부분 문제를 (l, Q[i]- 1) + (Q[i]+1, r)로 두면 되지 않나? 싶은데, 모든 감옥을 인덱스로 담기에는 메모리나 시간이 부족하다.
[Q의 인덱스] 남은 선택지는 Q의 인덱스 밖에 없으니 이걸로 dp 구간을 설정해보자.
Q의 인덱스로 구성해야 한다면 위와 다르게 닫힌 구간이 아닌 열린구간 (l, r)로 봐야한다. Q[l]+1부터 Q[r]-1까지 죄수 중 [l+1, r-1] 구간에 있는 죄수를 석방할 수 있고, 거기서 어느 구간에 있는 죄수들에게 뇌물을 줘야하는지 바로 계산할 수 있다.
따라서 점화식은 아래처럼 구할 수 있다.
rec(l, r) = min i=[l+1,r-1] rec(l, i) + rec(i, r) + pos[r] - pos[l] - 2 |
코드 보기
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_N = 102;
int dp[MAX_N][MAX_N], pos[MAX_N];
int rec(int l, int r){
if(l + 1 == r) return 0;
int& ret = dp[l][r];
if(ret != -1) return ret;
ret = 1e9;
for(int i=l+1;i<r;i++)
ret = min(ret, rec(l, i) + rec(i, r) + pos[r] - pos[l] - 2);
return ret;
}
int main() {
memset(dp, -1, sizeof dp);
int P, Q, i;
scanf("%d%d",&P, &Q);
pos[0] = 0, pos[Q+1] = P + 1;
for(i=1;i<=Q;i++) scanf("%d",&pos[i]);
sort(pos+1, pos+Q+1);
printf("%d",rec(0, Q+1));
return 0;
}
'Solved problems' 카테고리의 다른 글
BOJ 5042 나무 옮기기 (0) | 2020.06.08 |
---|---|
BOJ 12932 노래방 (0) | 2020.06.08 |
BOJ 1023 괄호 문자열 (1) | 2020.06.04 |
BOJ 17428 K번째 괄호 문자열 (0) | 2020.06.04 |
BOJ 3001 이상한 문제 (0) | 2020.06.03 |