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 | 31 |
Tags
- 공유기 원격 설정
- 1188 음식 평론가
- django windows 배포 에러
- 18233 러버덕
- 2961 도영이가 만든 맛있는 음식
- django settings.py
- java di
- 원격 연결 포트 포워딩
- 14711 java
- apache pythonpath
- 1188 java
- django apache deploy error
- 2643 java
- 2961 java
- 18233 java
- django 웹 페이지
- 18233 비트마스킹
- django 프로젝트 시작
- 2661 java
- django httpd error
- windows 원격 연결 설정
- The requested operation has failed!
- django The requested operation has failed!
- APPEND_SLASH = FALSE
- django
- windows apache wsgi 에러
- 2643 색종이 올려 놓기
- 14711 타일 뒤집기
- 2661 좋은 수열
- Problems occurred while performing provisioning operation
Archives
라이브러리는 도서관 아닌가요
백준 (BOJ) 18233 러버덕을 사랑하는 모임 java 백트래킹 본문
https://www.acmicpc.net/problem/18233
구상부터 시작해서 실제 코드를 짜는데 어려움이 많았던 문제.
실버 1이라길래, 다소 편한 마음으로 임했다가 명치 정통으로 맞았다.
쉽다는 의견들도 많은데, 개인적으로는 난이도 분배가 좀 ㅎ....
1. 첫 접근은 대강 '조합'을 이용해서 어떻게 해야 하는지 감을 잡을 수 있다. 20C10 --> 약 18만 번 --> brute force 가능
2. 각 정답 후보군의 탐색 횟수를 줄이기 위해 backtracking이 가능하다는 걸 알게 된다.
3. backtacking을 위한 recursive 돌리기
4. 또한 backtracking을 하기 위한 약간의(?) stack 개념 --> 후보군이 얼마만큼 쌓였느냐를 통해 (주어진 P에 맞춰) 더 쌓을 것인지 아니면 정답 판별을 할 것인지 결정한다. top을 쓰는 풀이도 있던데 써도 되고 안 써도 되지 싶다.
5. 정답을 찾는 즉시 모든 재귀 층을 무너뜨려야 하므로 flag (변수명: stopTrigger) 삽입하고, 종료 조건문도 각 재귀 반복 후의 지점에 삽입
6. 또한 각 탐색 시점마다 골라진 사람들의 총 min과 max의 값이 다르므로 사전에 계산해주어야 한다.
다음에 다시 풀어봐야지..
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N, P, E;
static int[][] arr;
static int[] stack, lava;
static boolean stopTrigger;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
P = Integer.parseInt(st.nextToken()); // Person, 줄 사람 수
E = Integer.parseInt(st.nextToken()); // 총 선물할 인형 수
arr = new int[N][2];
stack = new int[P];
lava = new int[N];
for(int i=0; i<N; ++i){
st = new StringTokenizer(br.readLine());
arr[i][0] = Integer.parseInt(st.nextToken());
arr[i][1] = Integer.parseInt(st.nextToken());
}
backtracking(0, 0);
StringBuilder sb = new StringBuilder();
for(int a : lava){
sb.append(a).append(" ");
}
System.out.println(stopTrigger ? sb : -1);
}
static void backtracking(int count, int s){
if(P != count){
for(int i=s; i<N; ++i){ // 해당 자릿수에 대한 backtracking 진행
stack[count] = i;
backtracking(count+1, i+1);
if(stopTrigger){
return;
}
}
}
else{ // P == count
int min=0, max=0;
for(int i=0; i<P; ++i){
min += arr[ stack[i] ][0];
max += arr[ stack[i] ][1];
}
if(E < min || max < E){ // 범위 체크
return; // 싯빠이
}
stopTrigger = true;
int diff = E - min;
for(int i=0; i<P; ++i){
lava[stack[i]] += arr[ stack[i] ][0];
if(diff != 0){
int remained = arr[ stack[i] ][1] - arr[ stack[i] ][0];
if(remained < diff){
lava[stack[i]] += remained;
diff -= remained; // diff 깎아 먹고
}
else {
lava[stack[i]] += diff;
diff = 0;
}
}
}
}
}
}
'알고리즘 문제' 카테고리의 다른 글
백준 (BOJ) 20058 마법사 상어와 파이어스톰 bfs, 구현 (0) | 2022.06.28 |
---|---|
백준 (BOJ) 12904 A와 B java 그리디 (0) | 2022.06.28 |
백준 (BOJ) 13019 A를 B로 java 그리디 (0) | 2022.06.11 |
백준 (BOJ) 23351 물주기 java 그리디 (0) | 2022.06.10 |
백준 (BOJ) 17213 과일 서리 java dp (0) | 2022.06.10 |
Comments