알고리즘/백준
BOJ 2613 숫자구슬 / C++
내이름은 킹햄찌
2022. 12. 4. 13:36
https://www.acmicpc.net/problem/2613
2613번: 숫자구슬
첫째 줄에 구슬의 개수 N과 그룹의 수 M이 주어진다. 둘째 줄에는 각 구슬이 적혀진 숫자가 왼쪽부터 차례로 주어진다. N은 300 이하의 자연수, M은 N이하의 자연수이며, 구슬에 적혀진 숫자는 100
www.acmicpc.net
아이디어
매개변수 탐색으로 각 그룹의 합의 최대값이 최소값이 되는 값을 찾고 그에 맞는 그룹을 찾으면 됩니다.
#include <iostream>
#include <vector>
using namespace std;
int N, M;
int totalSum;
vector<int> arr;
vector<int> group;
void input() {
cin >> N >> M;
arr.resize(N);
for (int i = 0; i < N; i++) {
cin >> arr[i];
totalSum += arr[i];
}
}
bool checkMin(int target) {
int k = 0;
int sum = 0;
int divCnt = 1;
for (auto iter : arr) {
//원소의 합이 t보다 작거나 같은 그룹을 만들어야 함
if (sum + iter > target) {
sum = 0;
divCnt++;
}
//그룹의 원소가 M보다 크다면 최솟값을 더 증가 시킬 수 있음
if (divCnt > M) return true;
sum += iter;
if (k < sum) k = sum;
}
//그룹의 원소 최대값이 mid보다 클경우 mid를 더 줄여야 함
return k > target;
}
void findGroup(int n) {
int sum = 0, cnt = 0;
for (int i = 0; i < N; i++) {
sum += arr[i];
if (sum > n) {
sum = arr[i];
M--;
cout << cnt << " ";
cnt = 0;
}
cnt++;
//남은 원소가 남은 M의 개수와 같다면
if (N - i == M) break;
}
//나머지는 1로 채움
while (M--) {
cout << cnt << " ";
cnt = 1;
}
}
int binarySearch(int l, int r) {
while (l < r) {
int mid = (r + l) >> 1;
//최대값이 더 커질 수 있을때
if (checkMin(mid)) {
l = mid + 1;
}
else {
r = mid;
}
}
return r;
}
void solution() {
int sol = binarySearch(1, totalSum);
cout << sol << "\n";
findGroup(sol);
}
int main(void) {
input();
solution();
}