Codeforces Round #307 Div2 C: GukiZ hates Boxes
解法
二分探索で間に合う最小の時間を探す。適当に決めた時間に対して、以下の操作を繰り返す。
- 残ってる人の中から1人を、残っている一番遠い箱まで派遣する。
- その人が時間内に一番遠い箱が片付け終わらないなら、可能な限り片付ける。
- 片付け終わるなら、残った時間でその一つ手前の箱も片付ける。
- それも終わるならまた一つ手前の…と繰り返していく。
こうすることで、時間を決めた時に間に合うかどうか判定できる。
コード
import java.util.Arrays; import java.util.Scanner; public class Main { private final long MAX_TIME = Long.MAX_VALUE / 2; public void solve() { Scanner sc = new Scanner(System.in); int pileNum = sc.nextInt(); int persons = sc.nextInt(); int[] boxes = new int[pileNum]; for (int i = 0; i < pileNum; i++) { boxes[i] = sc.nextInt(); } sc.close(); // 二分探索 long high = MAX_TIME; long low = 0; while (high - low > 1) { long time = (high + low) / 2; int[] copy = Arrays.copyOf(boxes, pileNum); int cur = pileNum - 1;// 今残ってる一番端の箱の位置 for (int i = 0; i < persons; i++) { while (cur >= 0 && copy[cur] == 0) { cur--; } long rest = time; rest -= (cur + 1); while (rest > 0 && cur >= 0) { if (rest >= copy[cur]) { // 時間に余裕がある時 rest -= copy[cur]; copy[cur] = 0; while (cur >= 0 && copy[cur] == 0) { cur--; } } else { // 余裕がない時 copy[cur] -= rest; rest = 0; } } } // 終わっているかどうか if (cur == -1 && copy[0] == 0) { high = time; } else { low = time; } } System.out.println(high); } public static void main(String[] args) { new Main().solve(); } }