3 solutions
-
0
题面描述
在一个包含两行和m列的糖果迷宫中,小A和小B从左上角出发,目标是到达右下角。小A在路径中尽量减少小B可以获得的糖果,而小B希望在小A走完后能尽可能多地吃到糖果。通过动态规划的方法,我们可以计算出小B最多能够吃掉的糖果数量。具体实现时,首先记录小A的路径及其获得的糖果,然后基于小A的路径计算小B的最大糖果数,最终得出小B可以获得的最大糖果总数。
题目分析
我们需要计算小A和小B分别在迷宫中移动时所能吃到的糖果数量。小A从左上角开始,向右或向下移动,直到到达终点。小B则从小A结束的地方开始,从终点位置返回到左上角,但不能吃小A吃过的糖果。小A的目标是尽量减少小B吃掉的糖果,而小B希望在小A走完后能吃到尽可能多的糖果。
思路
-
前缀和的计算:
- 我们需要计算小A和小B在每一列之前吃掉的糖果和。通过前缀和数组,我们能够快速获得任意区间内的糖果总数。
- 对于每一行,建立一个前缀和数组
qzs
,其中qzs[i][j]
表示第i行前j列的糖果总和。这样可以方便地计算出小A和小B在任意分割点之前和之后的糖果数量。
-
分割点的选择:
- 小A从左上角出发到达某个分割点,然后停止,接着小B从该分割点开始向右走至终点。在这个过程中,我们需要考虑每一个可能的分割点。
- 对于每一个分割点
i
,小A在分割点之前的总糖果数为qzs[0][i + 1]
(第一行的前缀和),而小B在该分割点之后的糖果数则为qzs[1][m] - qzs[1][i]
(第二行的前缀和减去分割点的糖果)。
-
最小化最大值:
- 对于每个分割点,计算小A在分割点之前和小B在分割点之后所能吃到的糖果数量。我们需要找出小B可能吃到的最大糖果数,并对所有分割点的结果取最小值。这样可以确保小A所吃的糖果数量最小化时,小B所能获得的糖果数量最大。
-
代码实现:
- 代码中首先读取糖果迷宫的数据,计算前缀和,然后遍历每一个可能的分割点,计算相应的糖果数量,最后输出小B能够吃到的最大糖果数。
时间复杂度
整个算法的时间复杂度为 (O(m)),因为我们只需遍历一次二维数组来计算前缀和,另外一次遍历进行计算,整体为线性复杂度。
代码实现
C++ 代码
Python 代码
Java 代码
代码注释总结
- 前缀和数组:
qzs[0][j+1]
记录小A在迷宫第0行的糖果和,qzs[1][j+1]
记录小B在迷宫第1行的糖果和。 - 分割点循环:遍历每一个可能的分割点,通过比较小B和小A的前缀和,计算当前点的最小损失值。
- 更新和输出:在遍历完所有列后,输出小B的最大糖果数量。
-
- 1
Information
- ID
- 58
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 5
- Tags
- # Submissions
- 190
- Accepted
- 79
- Uploaded By