Description
Super Hanhan(SH) loves playing all kinds of little games very much. Today rocket323 recommends a new game to SH.
The game’s name is “Eating stones”, and it’s played like this: in a single round, the game system will randomly generate a sequence of N numbers(all of these N numbers are unique) representing the size of stones, and place them from left to right in a single line. Each time the player can choose one stone to eat, and then get a score of P points, which equal to number of remaining stones which are smaller than the chosen stone and to the left of the chosen stone.
SH wants to maximize the score he can get, however, he can’t figure out the best strategy to reach the goal. So he asks you(a talented programmer) for help.
Please help the poor SH find out the best strategy and tell him the expected scores he can get under this strategy.
Input
There are multiple cases.
The first line is an integer T representing the number of test cases.
The following T lines each line representing a test case. For each case there is exactly one line containing a single number N, representing the number of stones in the game. (1 <= N <= 1000000)
Output
For each test case, output a line containing the answer in the following format:
Case #K: X
K is the case number starting from 1, and X must be printed as a real number with two-digit precision, and the last decimal digit must be rounded.
Sample Input
2 1 3
Sample Output
Case #1: 0.00 Case #2: 1.50
题目的意思看了大半天才懂。。。
题意不是直接求最大得分,而是求最大得分的期望值,注意末句“ 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; }