题目描述如下:25 个互不相等的数,每次比较 5 个数的相对大小,要求最大数和次大数,求最优策略下比较次数的期望值(是个确定的值)。T 组数据,每组输入 N,输出期望精确到小数点后 N 位。
据说此题为 HIT2018 春校赛 J 题,但因笔者当时未参加,真实性未知。通过观察样例输入输出,大胆猜测期望为 6.966666…,即 209/30,于是得到满分算法。
代码如下:
#include<stdio.h>
int main()
{
int n,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
if(n>1)
{
printf("6.9");
for(int i=2;i<n;i++)
printf("6");
printf("7\n");
}
else if(n==1)
printf("7.0\n");
else
printf("7\n");
}
return 0;
}
如果只从做题的角度看,本题过于简单。但若深究本题所言之最优策略,则方能达到校赛最后一题(据传)的水准。通过期望反推最优策略,根据 209 / 30 = 6 ∗ 1 / 30 + 7 ∗ 29 / 30 209/30 = 6 * 1/30 + 7 * 29/30 209/30=6∗1/30+7∗29/30 可得,最优策略很有可能需要小概率的 6 次比较和大概率的 7 次比较(显然,5 次比较不可能得出最大值和次大值)。若最优策略存在最多需要 8 次比较的情况,则 8 次比较的概率必小于 6 次比较的概率。下面给出一个策略,其期望恰好为 209/30,但笔者不能证明该策略为最优策略,也不能证明最优策略的唯一性。
将 25 个数分 5 组,记组名 ABCDE,每组 5 数比较,A 组数按从大到小记 A1, A2, A3, A4, A5,其它四组依此类推。前 5 次比较后,最大值和次大值必在 A1, A2, B1, B2, C1, C2, D1, D2, E1, E2 十数之中。第 6 次比较 A2, B1, C1, D1, E1 的相对大小,不妨设 B1 > C1 > D1 > E1,若 A2 > B1,则确定最大值 A1,次大值 A2,否则需要第 7 次比较。第 6 次比较后,可确定 C2, D1, D2, E1, E2 必不为最大值或次大值,第 7 次则比较剩下 5 个数,即 A1, A2, B1, B2, C1 的相对大小,即可确定最大值和次大值。该策略需要 6 次或 7 次比较,而需要 6 次比较的概率为最大值和次大值都被分到 A 组的概率,即从 25 个数中取 5 个数,最大值和次大值都被取到的概率,即 P ( N = 6 ) = C 23 3 C 25 5 = 1 30 P(N = 6) = \frac{C_{23}^3}{C_{25}^5} = \frac{1}{30} P(N=6)=C255C233=301 得出该策略比较次数的期望为 209/30。