일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- linkedlist
- 브루트포스
- 파이썬실습
- 백준1926
- Python
- 배열
- 컴퓨터 네트워크
- Stack
- 그래프
- 그래프이론
- Queue
- deque
- 티스토리챌린지
- 프로토콜
- 오블완
- dfs
- greedy
- 백준13901
- BFS
- Java
- 백트래킹
- 컴퓨터네트워크
- 인터넷
- 정렬
- 코딩테스트
- 시뮬레이션
- 백준3085
- 백준2823
- 백준2493
- 파이썬
- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- linkedlist
- 브루트포스
- 파이썬실습
- 백준1926
- Python
- 배열
- 컴퓨터 네트워크
- Stack
- 그래프
- 그래프이론
- Queue
- deque
- 티스토리챌린지
- 프로토콜
- 오블완
- dfs
- greedy
- 백준13901
- BFS
- Java
- 백트래킹
- 컴퓨터네트워크
- 인터넷
- 정렬
- 코딩테스트
- 시뮬레이션
- 백준3085
- 백준2823
- 백준2493
- 파이썬
- Today
- Total
Little cabin in the woods
[백준] 13164. 행복 유치원 (JAVA) 본문
이번에 풀어 볼 문제는 < 백준 13164번. 행복 유치원 > 이다.
https://www.acmicpc.net/problem/13164
📌 문제 탐색하기
목표
티셔츠를 만드는 최소 비용 구하기
해야 할 것
1. 티셔츠를 만드는 비용이 최소가 되도록 하려면 조를 어떻게 나눠야 할까?
2. 티셔츠를 만드는 비용 출력하기
입력
[첫 줄] 정수 N (원생의 수), K (조의 개수) ( 1 ≤ N ≤ 300,000 , 1 ≤ K ≤ N )
[둘째 줄] 원생들의 키를 나타내는 N개의 자연수, 원생들의 키는 오름차순 정렬되어 있음, 원생의 키는 10^9 이하
출력
티셔츠를 만드는 비용이 최소가 되도록 K개의 조로 나누었을 때, 티셔츠 만드는 비용을 출력하기
아이디어
1. 티셔츠를 만드는 비용이 최소가 되도록 하려면 조를 어떻게 나눠야 할까?
티셔츠를 만드는 비용 = ( 각 조의 키 최대값 ) - ( 각 조의 키 최소값 )
만약 1명만 포함된 조일 경우 최대값 = 최소값 이므로 비용은 0이 된다.
[예제1]의 상황을 살펴보자.
원생들은 1, 3, 5, 6, 10 순으로 정렬되어 있다.
티셔츠를 만드는 비용이 최소가 되려면 인접한 원생들 중 키 차이가 큰 원생들을 서로 다른 조로 쪼개야 한다.
[예제1]의 경우,
원생들 : 1 3 5 6 10
키 차이 : 2 2 1 4
이므로 6과 10을 일단 다른 조로 쪼개야 한다.
원생들은 오름차순으로 정렬되어 있기 때문에 차이가 가장 큰 인접한 원생들만 쪼개면 그룹 전체의 최대값 - 최소값도 줄어들게 된다.
6과 10을 다른 조로 쪼개면 원생들은 (1,3,5,6) 과 (10) 그룹으로 나뉘게 되고 이때의 비용은 5 + 0 = 5 이다.
이때 비용이 계산되는 과정을 살펴보면, 각 그룹의 비용은 인접한 원생들끼리의 키 차이의 합으로 계산된다.
다시 말해 (2+2+1) + (0) 이 되는 것이다.
여기서 그룹을 한 번 더 나눠야 한다면, 그 다음으로 키 차이가 큰 원생들을 쪼개야 한다.
그 다음으로 키 차이가 큰 원생들은 (1,3) 과 (3,5) 이다. 둘 다 키 차이는 동일하게 2인데 이 둘 중 어떤 원생들을 쪼개든 결과는 동일하다. 그 이유는 각 그룹의 비용이 결과적으로 인접한 원생들끼리의 키 차이의 합으로 계산되기 때문이다.
(1,3) 을 쪼개서 그룹을 (1),(3,5,6),(10) 으로 나누어도 비용의 합 = (0)+(2+1)+(0) = 3 이 되고,
(3,5) 을 쪼개서 그룹을 (1,3)(5,6),(10) 으로 나누어도 비용의 합 = (2)+(1)+(0) = 3 이 된다.
다시 말해 이 문제는 목표 그룹 수 k 개가 주어졌을 때, 인접한 원생들의 키 차이 값 중 가장 큰 (k-1) 개를 선택하여 그 차이를 가진 인접한 원생들을 같은 그룹에 속하지 않도록 나눠야 한다.
2. 티셔츠를 만드는 최소 비용 출력하기
일단 인접한 원생들의 키 차이 값을 모두 구한 뒤, 그 중 (k-1) 개를 선택하여 제거한다.
이후, 남은 키 차이 값을 모두 합하면 구하고자 하는 최소 비용이 나오게 된다
📌 코드 설계하기
1. input 입력을 받는다.
2. 인접한 원생들의 키 차이 값을 계산하여 리스트 diff 에 넣는다. ➡️ O(N-1)
3. diff를 내림차순으로 정렬한다. ➡️O(NlogN)
4. diff의 k-1번째 원소부터 끝 원소까지 모두 더한 뒤 출력한다. ➡️O(N-(k-1))
➡️ 전체 코드의 시간복잡도는 O(N) + O(NlogN) + O(N)
➡️ N의 최대값 = 300,000 이므로 전체 연산은 시간내에 수행 가능하다.
📌 정답 코드
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] firstLine = br.readLine().split(" ");
int N = Integer.parseInt(firstLine[0]);
int K = Integer.parseInt(firstLine[1]);
String[] secondLine = br.readLine().split(" "); // N개의 원소
List<Integer> diff = new ArrayList<>(); // N-1개의 원소
for(int i=0; i<N-1; i++){
Integer height = Integer.parseInt(secondLine[i+1])-Integer.parseInt(secondLine[i]);
diff.add(height);
}
diff.sort(Collections.reverseOrder());
long result = 0;
for(int i=K-1; i<N-1; i++){
result += diff.get(i);
}
System.out.println(result);
}
}
📌 알게 된 것
이 문제가 그리디인지 떠올리기 쉽지 않다...
'STUDY > 알고리즘&코딩테스트' 카테고리의 다른 글
[백준] 5212. 지구 온난화 (JAVA) (0) | 2025.01.15 |
---|---|
[백준]10157. 자리배정 (JAVA) (0) | 2025.01.14 |
[백준]18320. 2xN 예쁜 타일링(JAVA) (0) | 2025.01.12 |
[백준] 2529. 부등호 (JAVA) (0) | 2025.01.12 |
[백준] 2210. 숫자판 점프 (JAVA) (0) | 2025.01.08 |