有一款被誉为智力考验的纸牌游戏,名为“แคง (Kang)”。在这个游戏中,每张牌都有一个正整数分数。游戏开始时,你会拿到 $N$ 张牌握在手中,桌面上还正面朝上从左到右排列着另外 $M$ 张牌。你可以看到所有牌的分数,包括你手中拿到的牌以及桌面上摆放的牌。接下来,你可以从桌面上额外摸 $k$ 轮牌,必须按从左到右的顺序每次摸一张。在每一轮摸牌之后,你可以执行 1 次弃牌操作:将手中任意数量且分数相同的牌一起丢弃。你需要制定出牌策略,使得在完成 $k$ 轮从桌面摸牌和从手中弃牌之后,手中剩余牌的分数总和最小。
考虑以下示例:
假设开始时你手中有五张牌,分数分别为 $6, 3, 9, 6, 3$,而桌面上从左到右摆放的牌分数依次为 $4, 6, 9, 6$。
当 $k = 1$ 时:如果你只能从桌面上摸 1 张牌,当你摸起第一张牌后,你拥有的牌的分数变为 $6, 3, 9, 6, 3, 4$。随后你可以选择将分数相同的牌丢弃 1 次。最优的做法是选择将 2 张分数为 $6$ 的牌丢弃,从而使剩余牌的分数总和达到最小值 $3 + 9 + 3 + 4 = 19$。
当 $k = 2$ 时:如果你可以从桌面上摸 2 张牌,最优策略是:在摸起第一张分数为 $4$ 的牌后,选择丢弃一张分数为 $9$ 的牌,此时手中剩余牌的分数为 $6, 3, 6, 3, 4$。接着,当你摸起第 2 张分数为 $6$ 的牌时,你可以丢弃 3 张分数为 $6$ 的牌,使得剩余牌的分数总和达到最小值 $3 + 3 + 4 = 10$。
当 $k = 3$ 时:如果你可以从桌面上摸 3 张牌,最优策略是:当你摸起第一张牌后,手中牌的分数变为 $6, 3, 9, 6, 3, 4$。随后选择将分数相同的牌丢弃 1 次,最优的做法是将 2 张分数为 $3$ 的牌全部丢弃,手中剩下 $6, 9, 6, 4$。接着,当你摸起第 2 张分数为 $6$ 的牌时,你可以丢弃 3 张分数为 $6$ 的牌,手中剩下 $9, 4$。而当你第 3 次摸起分数为 $9$ 的牌时,你可以将 2 张分数为 $9$ 的牌全部丢弃,使得剩余牌的分数总和为 $4$。
当 $k = 4$ 时:如果你可以从桌面上摸 4 张牌,最优策略是:在摸起第一张分数为 $4$ 的牌后,选择丢弃一张分数为 $4$ 的牌,手中剩余牌的分数为 $6, 3, 9, 6, 3$。接着第 2 次摸起的牌分数为 $6$,最优做法是将 2 张分数为 $3$ 的牌全部丢弃,手中剩下 $6, 9, 6, 6$。第 3 次摸起的牌分数为 $9$,选择将 2 张分数为 $9$ 的牌全部丢弃。最后摸起最后一张分数为 $6$ 的牌时,你可以丢弃 4 张分数为 $6$ 的牌。这次弃牌后手中不再剩余任何牌,这意味着牌的分数总和为 $0$。
你的任务(Your Task)
对于 $k = 1, 2, 3, \ldots, M$,求出完成 $k$ 轮之后“手中剩余牌的最小分数总和”。
本题采用与常规格式不同的编程方式,该方式将在正式比赛中使用。关于使用方法,请参阅本题末尾的说明。
实现细节
你需要编写以下函数:
std::vector<long long> capsize(std::vector<int> A, std::vector<int> B)
参数说明如下:
- $A$ 是一个长度为 $N$ 的数组,表示初始时手中各张牌上的数字。
- $B$ 是一个长度为 $M$ 的数组,按从左到右的顺序表示桌面上摆放的各张牌上的数字。
- 该函数需要返回一个长度为 $M$ 的数组 $C$,表示当 $k = 1, 2, 3, \ldots, M$ 时,经过 $k$ 轮后手中牌可能达到的最小分数总和。
例如,如果 $A = [6, 3, 9, 6, 3]$ 且 $B = [4, 6, 9, 6]$,函数应当返回数组 $[19, 10, 4, 0]$。
数据范围
- $1 \le N, M \le 10^6$
- 对于每个满足 $1 \le i \le N$ 的 $i$,均有 $1 \le A[i] \le 10^9$
- 对于每个满足 $1 \le i \le M$ 的 $i$,均有 $1 \le B[i] \le 10^9$
子任务
| 子任务编号 | 该子任务最高分值 | 条件 |
|---|---|---|
| 1 | 5% | $N, M \le 5$ |
| 2 | 7% | $N \le 1\,000$ 且 $M = 1$ |
| 3 | 8% | $N, M \le 1\,000$,所有牌(包括手中的牌和桌面上展示的牌)上的数字两两不同 |
| 4 | 12% | $N, M \le 1\,000$,所有额外摸到的牌数值全部相同 |
| 5 | 16% | $N, M \le 1\,000$ |
| 6 | 28% | $N, M \le 100\,000$ |
| 7 | 24% | 无额外限制条件 |
说明
编程指南
在本题中,编写程序并将其提交到评测系统(Grader)的方式与参赛者需要自行编写输入读取和输出打印部分的常规格式不同。在本题中,参赛者只需在指定的函数内编写必要的计算部分。所有输入数据均可通过函数的参数获取,计算结果也同样必须通过函数返回。参赛者无需编写读取输入的代码,也无需编写输出代码。
参赛者将获得以下若干文件。参赛者只需按照题目要求修改唯一指定的文件,并将该文件提交至系统:
grader.cpp是负责读取输入和输出的主文件。kang.cpp是参赛者编写各项计算程序的文件,也是参赛者需要提交到系统的文件(在kang.cpp文件中禁止包含main()函数,但可以定义其他函数)。run_cpp.sh是参赛者可以调用以运行整个程序的文件。compile_cpp.sh是参赛者可以调用以编译程序的文件。
参赛者将获得一个可从系统下载的 .zip 压缩包,解压(extract)后包含上述全部 4 个文件。参赛者应当使用文本编辑器或 IDE 修改 kang.cpp 文件,并通过调用 compile_cpp.sh 或 run_cpp.sh 来编译或运行程序。
当参赛者调用 run_cpp.sh 运行程序时,程序将按照 grader.cpp 文件中的定义执行,“评测程序文件说明”一节解释了该文件的工作方式。