CF2041M Selection Sort

题目描述

![](https://cdn.luogu.com.cn/upload/vjudge_pic/CF2041M/d5dc69f2c95d765850bbfc6e16bfc04c742abf70.png) 每个选修算法课程的学生本周都需要提交一次作业。任务是实现一个 $O(n^2)$ 时间复杂度的算法,将给定的 $n$ 个整数按非递减顺序排序。Alice 已经完成了她的作业,她的实现如下所示: ``` int alice_sort(int *s, int n){ for(int i = 0; i < n; ++i){ for(int j = i + 1; j < n; ++j){ if(s[i] > s[j]){ int swap = s[i]; s[i] = s[j]; s[j] = swap; } } } return 0; } ``` 虽然你可以访问到 Alice 的代码,但你并不想直接照搬。你希望将 Alice 的排序函数作为你自己解决方案的一个构建模块。你可以通过以下两种方式使用她的函数,但每种方式最多只能使用一次。这两种操作的调用顺序可以任意。 - 前缀排序:选择一个长度 $i \in \{1, 2, \ldots, n\}$,调用 $\texttt{alicesort(}s, i\texttt{)}$。这会将数组 $s$ 的前 $i$ 个元素排序。 - 后缀排序:选择一个长度 $i \in \{1, 2, \ldots, n\}$,调用 $\texttt{alicesort(}s+n-i, i\texttt{)}$。这会将数组 $s$ 的后 $i$ 个元素排序。 由于排序算法的时间复杂度,执行一次前缀或后缀排序的代价为 $i^2$,其中 $i$ 是所选子数组的长度。你的目标是,按照上述规则,使用 Alice 的函数对输入数组 $s$ 的 $n$ 个整数进行非递减排序,并求出最小的总代价。 例如,设 $s=[3,2,5,5,4,1]$。我们可以先对长度为 $4$ 的后缀排序,数组变为 $[3,2,1,4,5,5]$。然后对长度为 $3$ 的前缀排序,数组变为 $[1,2,3,4,5,5]$,此时数组已排序。总代价为 $4^2+3^2=25$。再如,设 $s=[4,3,2,1]$,只需对长度为 $4$ 的前缀排序即可完成排序,总代价为 $4^2=16$。

输入格式

第一行包含一个整数 $n$,表示数组 $s$ 的元素个数。第二行包含 $n$ 个整数,表示 $s=[s_0, s_1, \ldots, s_{n-1}]$。 - $1 \le n \le 10^6$ - 对所有 $i$($0\le i < n$),有 $0\le s_i < 2^{31}-1$。

输出格式

输出一行一个整数,表示按照上述规则,使用 Alice 的函数将输入数组 $s$ 排序所需的最小总代价。

说明/提示

由 ChatGPT 4.1 翻译