题目的意思看了大半天才懂。。。
题意不是直接求最大得分,而是求最大得分的期望值,注意末句“ expected scores ”,每吃一次石子,位于这块石子左边而且size小于该石子的石子总数就是得分。以测试数据的第二个例子为例进行说明:
N为3表明有3个石子,这三个石子的size是随机的,但必定互异。由此我们不妨设这三个石子的size分别为1,2,3。由于size是随机的,所以石子从左到右呈直线排列后size组成的数列有3!=6种可能,即是“123”,“132”,“213”,“231”,“312”,“321”。实际的数列可能是其中任意一种,要得到最大分数,“ the best strategy”必然是从右吃到左,于是就产生了6个可能的最大得分:3,2,2,1,1,0,于是在这一个例子中,我们要求的“ expected scores ”,就是(3+2+2+1+1+0) / 6 = 1.5。
通过上例我们不难发现,每一种size的排列对应的最大得分就是该数列从右到左的逆序数,比如上例中6种排列的逆序数分别就是3,2,2,1,1,0,于是求“ expected scores”的问题就转化为求size的N!种排列中逆序数的期望。
那么,逆序数的期望又当如何求?实际上就等于N个数的升序排列的逆序数再除以2.下面对这个结果做简要的分析,我数学不好,严格证明就。。。
为了便于分析,同时又不失一般性,现假设随机产生的N个数为1,2,3,...,n。显然,排列S1={1,2,3,...,n}的逆序数为MAX=n(n-1)/2, 这是N!种排列中的最大逆序数,而S2={n,n-1,...,1}的逆序数是MIN = 0,这是N!种排列中的最小逆序数。这两种排列的逆序数的平均值为 MAX / 2。逆序数第二大的排列和逆序数第二小的排列分别是{2,1,3,...,n}, {n,n-1,...,3,1,2},显然,这两个排列的逆序数分别是MAX - 1和MIN + 1,两者平均值也是MAX / 2. 事实上,通过观察我们可以发现,当我们将S1和S2中的数看成一一对应,即是1对应n,2对应n - 1,.....,n对应1,然后当S1中的数因为调整位置而使得逆序数小了k,即成为MAX - k时,S2中对应的数做对应的位置调整时必使得其逆序成为MIN + k,于是均值仍是MAX / 2.
通过以上糟糕的分析,我们可以得出结论,N个互异数构成的所有排列的平均逆序数为N(N - 1)/2, 这也即是N个互异数构成的数列的逆序数的数学期望。
于是有以下代码:
#include <iostream> #include <cstdio> using namespace std; int main() { int T, ca = 1, N; double p; scanf("%d", &T); while(T--) { scanf("%d", &N); p = N*(N-1)/4.0; printf("Case #%d: %.2lf\n", ca++, p); } return 0; }