拉面店里有 $N$ 位朋友 $F_0, \dots, F_{N-1}$ 和 $N$ 种拉面 $R_0, \dots, R_{N-1}$。每位朋友 $F_i$ 对拉面类型 $R_j$ 都有一定的亲和度 $A_{i,j}$ —— 亲和度越高,朋友 $F_i$ 越喜欢拉面 $R_j$。每位朋友对不同拉面的亲和度各不相同,即对于 $j \neq j'$,有 $A_{i,j} \neq A_{i,j'}$。当然,亲和度 $A_{i,j}$ 也有可能小于 $0$。
假设朋友们多次光顾拉面店。在每次光顾时,没有两位朋友可以吃同一种拉面(供应不足)。假设朋友们按照某个排列 $\pi_0, \dots, \pi_{N-1}$(即 $0, \dots, N-1$ 的一个排列)的顺序领取拉面。那么,朋友 $F_{\pi_0}$ 将领取他们最喜欢的拉面(即亲和度最高的拉面),朋友 $F_{\pi_1}$ 将领取除 $F_{\pi_0}$ 已领取的拉面之外他们最喜欢的拉面,以此类推。换句话说,$F_{\pi_i}$ 将在未被 $F_{\pi_0}, \dots, F_{\pi_{i-1}}$ 领取的拉面中选择他们最喜欢的拉面。
某个排列 $\pi$ 的“优良度”(goodness)是朋友们所领取的拉面对应的亲和度之和。换句话说,如果朋友 $i$ 领取了类型为 $\sigma(i)$ 的拉面,则 $\pi$ 的优良度为 $\sum_{i=0}^{N-1} A_{i, \sigma(i)}$。
你的目标是找到一个具有最大优良度的排列 $\pi$。你可以通过实验朋友们领取拉面的不同顺序(即多次光顾拉面店)来实现。目标是在不需要过多光顾次数的情况下找到一个最优排列。
交互
你需要实现以下函数:
std::vector<int> find_order(int N);
其中 $N$ 是朋友的数量。该函数应返回一个具有最大优良度的 $0, \dots, N-1$ 的排列 $\pi$。为了实现这一点,你可以重复调用以下函数,最多调用 750 次:
std::vector<std::pair<int, int>> query(const std::vector<int>& order);
该函数接收一个 $0, \dots, N-1$ 的排列作为输入(由参数 order 表示),并返回一个包含 $(\sigma(i), A_{i, \sigma(i)})$ 的列表,其中 $\sigma(i)$ 是如果朋友们按照 order 给出的顺序领取拉面时,朋友 $i$ 所领取的拉面类型。
数据范围
- $1 \le N \le 75$
- $|A_{i,j}| \le 2\,000\,000$
- 科学委员会的标准解法对于某些常数 $c, k \ge 1$ 最多需要 $cN^k$ 次查询。为了不给测试基础设施增加负担,你最多可以调用
query750 次,这充分反映了标准解法的实际性能。
子任务
| # | 分值 | 数据范围 |
|---|---|---|
| 1 | 5 | $N = 5$ |
| 2 | 15 | $N = 15$ |
| 3 | 20 | $N = 30$ |
| 4 | 20 | $N = 45$ |
| 5 | 20 | $N = 60$ |
| 6 | 20 | $N = 75$ |
样例
| 选手行为 | 委员会行为 |
|---|---|
调用 find_order(2)。 |
|
query({0, 1}) |
|
{{0, 9}, {1, 0}} |
|
query({1, 0}) |
|
{{1, 5}, {0, 5}} |
|
find_order(2) 返回 {1, 0}。 |
在这个例子中,有 $N=2$ 位朋友,对于 $N=2$ 种拉面,亲和度 $A_{i,j}$ 如下:
| $A$ | 0 | 1 |
|---|---|---|
| 0 | 9 | 5 |
| 1 | 5 | 0 |
交互从委员会调用你的函数 find_order(2) 开始。然后你的函数查询了两个可能的排列:{0, 1} 和 {1, 0}。前者获得的优良度为 $0+9 = 9$,而后者获得的优良度为 $5+5 = 10$。函数随后返回两者中较好的一个,即 {1, 0}。返回的排列具有最大可能的优良度,符合要求。