본문 바로가기
PS

[BAEKJOON] 13164 행복 유치원 (C++)

by bin1225 2023. 6. 30.

https://www.acmicpc.net/problem/13164

 

13164번: 행복 유치원

입력의 첫 줄에는 유치원에 있는 원생의 수를 나타내는 자연수 N(1 ≤ N ≤ 300,000)과 나누려고 하는 조의 개수를 나타내는 자연수 K(1 ≤ K ≤ N)가 공백으로 구분되어 주어진다. 다음 줄에는 원생들

www.acmicpc.net

문제

원생의 수만큼 원생의 키가 주어진다.

N명의 원생들을 K개의 그룹으로 만드는데, 그룹내에서 가장 큰 원생과 작은 원생의 키차이만큼 비용이 발생한다.

1명의 원생으로 이루어진 경우는 비용이 0이다. (자기자신 - 자기자신 = 0)

비용을 최소로 만드는 경우의 비용을 구하는 문제

 

접근

그룹은 많이 많들 수 있을 수록 이득이다. 만약 N명의 원생에 대하여 N개의 그룹을 구성할 수 있다면 총 비용은 0이다.

그럼 최악은? 1개의 그룹인 경우이다. 이 경우 배열의 맨 처음과 끝 값의 차만큼 비용이 발생한다.

최악의 상태에서 그룹을 만들어가면서 비용을 줄이는 것이 접근방법이다.

 

그룹을 만든다는 것은 두 원생사이의 접점을 끊는다고 생각하면 직관적이다. (원생은 키순서대로 주어진다)

접점을 끊으면 두 원생사이의 키차이만큼 비용이 감소한다.

그럼 이제 결정할 것은 어떤 원생사이의 접점을 끊을 것인가이다. -> 가장 차이가 큰 원생 사이의 접점부터 차례로 K-1개를 끊어주면 된다. (K개의 그룹을 구성하기 위해서는 K-1개의 구분점이 필요한다)

따라서 각 원생사이의 차이를 모두 vector에 넣고, 큰 것부터 차례로 K-1개 확인해서 초기 최대발생 비용에서 제외해주면 최소값을 구할 수 있다.

 

코드

#include <iostream>
#include <vector>
#include <algorithm>

#define endl "\n"

using namespace std;

int N, K, ans;
int height[300000];
vector<int> W;
void Input() {
	cin >> N >> K;
	for (int i = 0; i < N; i++) {
		cin >> height[i];
	}
}

void Solve() {
	for (int i = 1; i<N; i++) {
		ans += height[i] - height[i - 1];
		W.push_back(height[i] - height[i - 1]);
	}
	sort(W.begin(), W.end(), greater<int>());
	for (int i = 0; i < K - 1; i++) {
		ans -= W[i];
	}
	cout << ans;
}


int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	freopen("input.txt", "r", stdin);
	Input();
	Solve();


	return 0;
}

 

그리디는 방법만 생각하면 코드는 간단하게 짤 수 있는 것 같다.

'PS' 카테고리의 다른 글

[BAEKJOON] 20444 색종이와 가위 (C++)  (0) 2023.07.08
[BAEKJOON] 2206 벽 부수고 이동하기 (C++)  (0) 2023.07.07
[BAEKJOON] 1092 배 (C++)  (0) 2023.06.29
[BAEKJOON] 15686 치킨 배달 (C++)  (0) 2023.06.26
[BAEKJOON] 15663 N과 M(9) (C++)  (0) 2023.06.25