https://www.acmicpc.net/problem/17179
17179번: 케이크 자르기
첫 번째 줄에 자르는 횟수가 담긴 목록의 길이 N과 자를 수 있는 지점의 개수 M, 그리고 롤 케이크의 길이인 정수 L이 주어진다. (1 ≤ N ≤ M ≤ 1,000, 1 < L ≤ 4,000,000) 다음 M줄에 걸쳐 자를 수 있는
www.acmicpc.net
케이크를 자를건데 자를 수 있는 M가지 지점이 있고 Q번 잘랐을때 가장 작은 조각의 길이를 최대화 하는 문제입니다.
완전탐색부터 접근을 해봅시다.
가장 떠올리기 쉬운 완전탐색 접근은 "가장 작은 조각이 Xcm이상일때 자르는 것이 가능한가"에 대해 모든 2 ~ L까지 해보는 것입니다.
모든 2 ~ L에 대해 확인하며 잘라본다면 특정 시점부터 불가능한 지점이 나올것이고, 직전 지점이 정답일 것입니다.
완전탐색을 위 방법 그대로 시도한다면 시간초과입니다.
위와 같은 완전탐색 접근을 하면서 특정 시점부터 불가능한 지점 이라는 관찰을 통해 정답이 단조성을 띈다는 것을 알 수 있습니다.
정답이 단조성을 띄기 때문에 이분탐색을 통한 최적화가 가능합니다.
code(c++)
#include <bits/stdc++.h>
#define endl "\n"
#define NM 303030
#define MAX 101010
#define BIAS 1048576
#define MOD 20170805
#define X first
#define Y second
#define INF 0x3f3f3f3f
#define FOR(i) for(int _=0;_<(i);_++)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(v) v.begin(), v.end()
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int n, m, l;
int arr[1111];
tuple<int, int> ok(int x){
int cnt = 0;
int prev = 0;
for (int k = 0 ; k <= m; k++){
if (arr[k] - prev >= x){
cnt++;
prev = arr[k];
}
}
return {cnt, x};
}
void input() {
cin >> n >> m >> l;
for (int i = 0; i < m; i++) cin >> arr[i];
arr[m] = l;
}
void pro() {
for (int i = 0 ; i < n ; i++){
int x;
cin >> x;
int s = 0;
int e = arr[m - 1];
int ans = 0;
while (s <= e){
int mid = s + e >> 1;
auto [cnt, tmp] = ok(mid);
if (cnt > x){
s = mid + 1;
ans = max(ans, tmp);
}else{
e = mid - 1;
}
}
cout << ans << endl;
}
}
int main() {
fastio;
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
input();
pro();
return 0;
}
'알고리즘 문제 풀이' 카테고리의 다른 글
백준 20425 아침은 고구마야(Easy) (1) | 2024.03.14 |
---|---|
프로그래머스 기사단원의 무기 (1) | 2024.02.26 |
백준 5546 파스타 (0) | 2024.02.26 |
백준 1756 피자굽기 (0) | 2024.02.22 |
백준 31230 모비스터디 (1) | 2024.02.12 |