※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 15337번 문제인 Starting a Scenic Railroad Service이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/15337
15337번: Starting a Scenic Railroad Service
Jim, working for a railroad company, is responsible for planning a new tourist train service. He is sure that the train route along a scenic valley will arise a big boom, but not quite sure how big the boom will be. A market survey was ordered and Jim has
www.acmicpc.net
이 문제는 policy-1과 policy-2의 두 문제를 해결해야하는 문제이다.
policy-1은 각 구간에 대해서 "이 구간과 겹치는 다른 구간의 수"가 가장 많은 구간을 찾으면 되고, policy-2는 가장 많은 사람들이 겹쳐 예약한 구간을 찾는 것으로 해결이 가능하다. 각 policy는 O(N)의 시간에 구할 수 있다.
policy-1은 이 구간과 "겹치지 않는" 구간의 수를 세어 전체 구간의 개수에서 빼주는 것으로 계산할 수 있다.
구체적으로, 한 구간을 [L, R]이라고 하면 겹치지 않는 구간 [x,y]는 y<=L이거나 R<=x를 만족하게 된다.
따라서, prefix sum을 이용해서 각 index보다 작은 y의 개수 배열과 각 index보다 큰 x의 개수 배열을 전처리하고 각 구간을 한번씩 살피면 O(N)으로 policy-1을 해결할 수 있다.
policy-2는 간단히 1차원 imos법을 통해 O(N)으로 해결할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
int imos[100001];
int psum[100001];
int ssum[100001];
pair<int, int> seg[200000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N; cin >> N;
for (int i = 0; i < N; i++) {
int x, y; cin >> x >> y;
imos[x]++, imos[y]--;
psum[y]++, ssum[x]++;
seg[i] = { x,y };
}
int ans1 = 0, ans2 = 1000000007;
for (int i = 1; i < 100001; i++) {
imos[i] += imos[i - 1];
ans1 = max(ans1, imos[i]);
}
for (int i = 0; i < 100000; i++) {
psum[i + 1] += psum[i];
}
for (int i = 99999; i > -1; i--) {
ssum[i] += ssum[i + 1];
}
for (int i = 0; i < N; i++) {
int x = seg[i].first, y = seg[i].second;
int tmp = psum[x] + ssum[y];
ans2 = min(ans2, tmp);
}
cout << N - ans2 << ' ' << ans1;
}
'BOJ' 카테고리의 다른 글
[BOJ 1781 // C++] 컵라면 (0) | 2022.01.06 |
---|---|
[BOJ 1516 // C++] 게임 개발 (0) | 2022.01.05 |
[BOJ 1536 // C++] Dance, Dance (0) | 2022.01.03 |
[BOJ 17400 // C++] 깃발춤 (0) | 2022.01.02 |
[BOJ 10976 // C++] 피난 (0) | 2022.01.01 |