AOJ0564 Bug Party
問題リンク Bug Party
- 解法
「X匹の虫をシャーレに入れることができるか」というXについて2分探索して解きました。
各Xについてのチェックについて説明します。
まず、虫をX匹選んだとして、許容量の一番小さい虫がボトルネックとなります。その虫の放出量をAk、許容量をBkとすると、
ΣAi(許容量がBk以上の虫の中からX-1匹) ≦ Bk * X - Ak
という不等式を満たしたらX匹をシャーレに入れることができることになります。ボトルネックとなる虫以外に虫をX-1匹選ぶわけですが、これは許容量Bk以上の虫の中から放出量が小さい順にX-1匹採用すれば最善であることが分かります。以上から、ボトルネックとなる虫を許容量が大きい順に試していき、同時に優先度付きキューなどで放出量を管理していけば、各XについてO(N log N)くらいでチェックできます。
- ソース
import java.util.Arrays; import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner; //Bug Party public class AOJ0564 { class B implements Comparable<B>{ int a, b; public B(int a, int b) { this.a = a; this.b = b; } public int compareTo(B o) { return o.b-b; } } int n; B[] r; boolean ok(int x){ if(x==0)return true; PriorityQueue<B> q = new PriorityQueue<B>(x, new Comparator<B>() { public int compare(B o1, B o2) { return o2.a-o1.a; } }); long A = 0; for(int i=0;i<x-1;i++){ A+=r[i].a; q.add(r[i]); } for(int i=x-1;i<n;i++){ long w = (long)x*r[i].b-r[i].a; if(A<=w)return true; A+=r[i].a; q.add(r[i]); A-=q.poll().a; } return false; } void run(){ Scanner sc = new Scanner(System.in); n = sc.nextInt(); r = new B[n]; for(int i=0;i<n;i++)r[i]=new B(sc.nextInt(), sc.nextInt()); Arrays.sort(r); int L = 0, R = n; while(R-L>1){ int m = (L+R)/2; if(ok(m))L=m; else R=m; } System.out.println(ok(R)?R:L); } public static void main(String[] args) { new AOJ0564().run(); } }