cote/Intermediate
항해99 백준 2343번 // 블루레이 강의
geminanolja
2025. 1. 17. 09:56
https://www.acmicpc.net/problem/2343
강토는 강의의 동영상을 블루레이에 저장하려고 합니다. 총 NNN개의 강의가 있으며, MMM개의 블루레이를 사용하여 강의를 저장해야 합니다. 이때 다음 조건을 만족해야 합니다:
블루레이 하나에 포함된 강의들은 순서가 바뀌면 안 됩니다.각 강의의 길이는 주어지며, 하나의 블루레이에 녹화되는 강의들의 총 길이가 블루레이의 용량을 초과하면 안 됩니다.MMM개의 블루레이를 모두 사용하는 상황에서, 블루레이의 크기(용량)를 최소화해야 합니다
그리디 알고리즘과 이진탐색
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
// 블루레이 크기로 강의들을 나눌 수 있는지 확인하는 그리디 알고리즘을 이용한 함수
bool isPossible(const vector<int>& lectures, int n, int m, int maxSize)
{
int count = 1; // 사용한 블루레이 개수
int currentSum = 0; // 현재 블루레이에 들어간 강의 길이 합
for (int lecture : lectures)
{
if (currentSum + lecture > maxSize)
{
count++; // 새로운 블루레이 사용
currentSum = lecture; // 현재 블루레이에 강의 추가
if (count > m)
{
return false; // 블루레이 개수 초과
}
}
else
{
currentSum += lecture;
}
}
return true;
}
// 가능한 최소 블루레이 크기를 찾는 이분탐색 수행하는 함수
int findMinimumBluraySize(const vector<int>& lectures, int n, int m)
{
int left = *max_element(lectures.begin(), lectures.end()); // 가장 긴 강의의 길이
int right = accumulate(lectures.begin(), lectures.end(), 0); // 모든 강의 길이 합
int result = right;
while (left <= right)
{
int mid = (left + right) / 2; // 중간 크기
if (isPossible(lectures, n, m, mid))
{
result = mid; // 가능한 경우 결과 저장
right = mid - 1; // 더 작은 크기 탐색
}
else
{
left = mid + 1; // 더 큰 크기 탐색
}
}
return result;
}
int main()
{
int n, m; //1<=m<=n=100,000
cin >> n >> m;
vector<int> lectures(n);
for (int i = 0; i < n; i++)
{
cin >> lectures[i];
}
cout << findMinimumBluraySize(lectures, n, m) << endl; // 결과 출력
return 0;
}
9개의 lectures, 3개의 블루레이로 나누기
1,2,3,4,5,6,7,8,9
1. 초기
left =9; right = 45; mid=27;
isPossible(lectures, 9,3, 27)
27보다 작은 면 1,2,3,4,5,6=21
21+7은 28로 count++해주고 currentLecture = 7
7+8+9=24 로 가능
return 27(result=27, right=27-1)
isPossible( lectures, 9,3, 26)
left =9; right = 26; mid=17;
1,2,3,4,5 count1
6 7 8= 21 count2
9 = count 3 -> return 17
isPossible(lectures, 9,3,right = 16)
left =9, right =16, mid =12;
1,2,3,4
5,6,
7,8
9
count=4
left 13