P12757 [POI 2017 R3] 厨师 Cook【交互题暂未配置】

题目背景

翻译来自于 [LibreOJ](https://loj.ac/p/5065)。

题目描述

**题目译自 [XXIV Olimpiada Informatyczna — III etap](https://sio2.mimuw.edu.pl/c/oi24-3/dashboard/) [Kucharz](https://szkopul.edu.pl/problemset/problem/9NFtPM59qGWa7wdn570ifuP0/statement/)** 厨师 Bajtazar 在一家餐厅工作,需处理 $n$ 份待烹饪的订单。每份订单记录在一张纸条上,纸条按序钉在尖桩上。Bajtazar 只能从顶部取下纸条,依次完成订单。烹饪耗时,他希望尽快完成所有订单,且不必逐一处理。假设尖桩上剩余 $k$ 份订单,他可选择以下操作: - 取顶部一份订单,耗时 $\texttt{jeden}(k)$ 烹饪。 - 若 $k > 1$,取顶部两份订单,耗时 $\texttt{dwa}(k)$ 烹饪。 - 若 $k > 1$,取顶部 $\lfloor k/2 \rfloor$ 份订单,耗时 $\texttt{polowa}(k)$ 烹饪。 Bajtazar 的初始能量为 $e$。第三种操作(取一半订单)极耗体力,降低 $1$ 单位能量;第一种操作(单份订单)是他的专长,增加 $1$ 单位能量。能量不得低于 $0$。他不关心最终能量,只求最短时间内完成所有订单。 编写程序,通过与提供 Bajtazar 状态和厨房信息的库交互,找出最短的订单完成时间。本题需特别注意内存限制。 ### 交互方式 提供以下函数: - $\texttt{dajn}, \texttt{daje}$ $\texttt{dajn}$ 返回整数 $n$,表示订单数量;$\texttt{daje}$ 返回整数 $e$,表示 Bajtazar 初始能量。 ```cpp // C/C++ int dajn(); int daje(); // Pascal function dajn: LongInt; function daje: LongInt; ``` - $\texttt{jeden}(k), \texttt{dwa}(k), \texttt{polowa}(k)$ 返回当尖桩上有 $k$ 份订单时,分别烹饪一份、两份或 $\lfloor k/2 \rfloor$ 份订单的耗时。若 $k=1$,$\texttt{dwa}(k)$ 和 $\texttt{polowa}(k)$ 无意义。耗时为 $1$ 至 $10^7$ 的整数。 ```cpp // C/C++ int jeden(int k); int dwa(int k); int polowa(int k); // Pascal function jeden(k: LongInt): LongInt; function dwa(k: LongInt): LongInt; function polowa(k: LongInt): LongInt; ``` - $\texttt{odpowiedz}(wynik)$ 向库报告最短完成时间 $wynik$,调用后程序终止。 ```cpp // C/C++ void odpowiedz(int wynik); // Pascal procedure odpowiedz(wynik: LongInt); ``` 程序不得读取任何数据(标准输入或文件),不得写入文件或标准输出,可写入标准错误输出(`stderr`,但耗时)。可多次查询库。 「文件」中提供了示例库,用于测试程序形式正确性。库从标准输入读取以下格式数据: - 第一行:两个整数 $n, e$; - 第二行:$n$ 个 $[1, 10^7]$ 内的整数,为 $\texttt{jeden}$ 在 $k=1,\ldots,n$ 的值; - 第三、四行:$\texttt{dwa}$ 和 $\texttt{polowa}$ 的值(同格式,$k=1$ 值无意义)。 示例输入见文件 `kuc0.in`。调用 $\texttt{odpowiedz}$ 后,库输出答案至标准输出。 目录内还有示例程序 `kuc.c`, `kuc.cpp`, `kuc.pas`,使用库但不正确,仅在最后调用 $\texttt{jeden}$,其余用 $\texttt{polowa}$。 编译命令: - C: `gcc -O2 -static ckuclib.c kuc.c -lm -std=gnu99` - C++: `g++ -O2 -static ckuclib.c kuc.cpp -lm -std=c++11` - Pascal: `ppc386 -O2 -XS -Xt kuc.pas` 程序与库文件需在同一目录。

输入格式

见交互方式。

输出格式

见交互方式。

说明/提示

以下是程序示例运行过程: | C/C++ | Pascal | 结果 | | :--: | :--: | :--: | | `n = dajn();` | `n := dajn;` | `3` | | `e = daje();` | `e := daje;` | `1` | | `p[3] = polowa(3);` | `p[3] := polowa(3);` | `1` | | `p[2] = polowa(2);` | `p[2] := polowa(2);` | `4` | | `j[2] = jeden(2);` | `j[2] := jeden(2);` | `2` | | `j[1] = jeden(1);` | `j[1] := jeden(1);` | `5` | | `d[2] = dwa(2);` | `d[2] := dwa(2);` | `6` | | `odpowiedz(7);` | `odpowiedz(7);` | - | 上述程序运行在形式上正确,但未必给出最优结果。从数据可知,操作 $\texttt{polowa}$ 和 $\texttt{dwa}$(耗时 $p[3]+d[2]=7$)优于一次 $\texttt{polowa}$ 和两次 $\texttt{jeden}$(耗时 $p[3]+j[2]+j[1]=8$)。因 $p[3]=1, j[3] \geq 1$,不宜在 $k=3$ 时选 $\texttt{jeden}$。但 $e=1$ 限制了两次 $\texttt{polowa}$。若不知 $\texttt{dwa}(3)$ 耗时,无法确认 $\texttt{dwa}$ 后接 $\texttt{jeden}$ 是否更优。 详细子任务附加限制及分值如下表所示。 | 子任务 | 附加限制 | 分值 | | :---: | :--: | :---: | | $1$ | $n, e \leq 1000$ | $12$ | | $2$ | $n, e \leq 50000$ | $8$ | | $3$ | $n, e \leq 1000000$ | $80$ |