티스토리 뷰
Cloud Computing
(http://codeforces.com/problemset/problem/1070/C)
\(1\sim n\)번 칸에서 각각 최대 \(k\)개의 코어를 사야 하는데,
당연히 살 수 있는 코어 중에서 가격이 싼 것 부터 차례대로 사는게 이득이다.
그렇다고 계획들을 정렬한 뒤 싼 것부터 하나하나 추가해가다보면, 어떤 칸에서 코어를 \(k\)개 넘게 샀는지를 확인하기 힘들다.
그래서 계획별로 보지 않고, 칸 별로 어떤 계획을 사용할지를 확인해야한다.
현재 \(i\)번째 칸에서 적용할 계획을 확인하고 있다면, 구간에 \(i\)가 포함되는 계획들을 찾아야 한다.
어차피 \(1\)번째 칸부터 \(n\)번째 칸까지 차례대로 볼 것이므로,
\(i\)가 계획의 시작점일 때 계획 후보에 넣고, 끝점일 때 빼면 된다.
구체적으로, 적용되는 구간이 \(l\)부터 \(r\)까지인 계획은 \(l\)번째 칸에 계획을 넣도록 체크해두고, \(r\)번째 칸에 계획을 빼도록 체크해둔 뒤 \(i\)번째 칸에서는 \(i\)번째 칸에서 넣을 계획은 넣고 뺄 계획은 빼면 된다.
이제 \(i\)번째 칸에서 사용할 수 있는 계획들은 찾았으니, 어떤 계획을 사용할지를 정해야한다.
다르게 생각하면 '얼마짜리 코어 까지 사야지 \(k\)개를 채울 수 있을까?'를 묻는 것인데,
이 질문을 이분탐색으로 찾을 수 있다.
현재 사용할수 있는 계획의 코어 가격이 \(p\)고 개수가 \(c\)면 배열의 \(p\)번째 칸에 \(c\)개를 더해둔다.
그러면 배열에서 \(1\sim t\)까지 원소의 합이 \(k\)를 넘을 때 \(t\)의 최솟값이 위 질문의 답이다.
써야하는 돈도 마찬가지로 배열을 만들어 \(1\sim t\)까지이니 그만큼 답에 더해주면 된다.
구간합도 펜윅트리, 세그먼트트리를 쓰면 \(\log\)시간 안에 구할 수 있으니 총 \(O(n\log^2{p})\)만에 답을 찾을 수 있다.
'문제' 카테고리의 다른 글
Codeforces 1077F1, 1077F2 Pictures with Kittens (easy, hard version) (0) | 2018.11.20 |
---|---|
BOJ 2867 수열의 값 (0) | 2018.11.11 |
BOJ 1819 불끄기 (0) | 2018.10.25 |
BOJ 12945 재미있는 박스 정리 (0) | 2018.09.26 |
BOJ 12932 노래방 (0) | 2018.09.20 |