返回顶部

列队春游

$\quad $ 实在蒟蒻,不看题解就只能对着电脑发呆,想了一个脚指头都能想出来的\(O(n \times n!)\) 的暴力做法。

$\quad $ 也是看了好多题解才大概明白式子推法。

$\quad $ 先考虑枚举每个可能的视野长度,那么就会有;
\begin{aligned}
ans&=\sum _{i=1}^{n}{i \times P(i)}\\&=\sum _{i=1}^{n}{\sum _{j=i}^{n}{P(j)}}\\
&=\sum _{i=1}^{n}{P(j>=i)}
\end{aligned}

$\quad $ 此时再计算后面部分的值。设身高不小于第 \(i\) 个人(不包括自己)的人数为 \(k_i\) ,那么就会有:

\[ans=\sum _{i=1}^{n}{\sum _{j=1}^{n}{\frac {(n-j+1) \times A^{k_i} _{n-j} }{A ^{k_i+1}_{n}}}} \]

$\quad $ 摘抄一下题解解释(doge)

$\quad $ 然后就是“快乐化简”:

\begin{aligned}
ans&=\sum _{i=1}^{n}{\sum _{j=1}^{n}{\frac {(n-j+1) \times A^{k_i} _{n-j} }{A _{n}^{k_i+1}}}}\\
&=\sum _{i=1}^{n}{\sum _{j=1}^{n}{}\frac {(n-j+1)\times {}\frac {(n-j)!}{(n-j-k_i)!}}{\frac {n!}{(n-k_i-1)!}}}\\
&=\sum _{i=1}^{n}{{\frac {(n-k_i-1)!}{n!}\times {\sum _{j=1}^{n}{\frac {(n-j+1)!}{(n-j-k_i)!}}}}}\\
&=\sum _{i=1}^{n}{\frac {(n-k_i-1)!\times (k_i+1)!}{n!}\times \sum _{j=1}^{n}{\frac {(n-j+1)!}{(n-j-k_i)!\times (k_i+1)!}}}\\
&=\sum _{i=1}^{n}{\frac {(n-k_1-1)!\times (k_1+1)!}{n!}\times \sum _{j=1}^{n}{C _{n-j+1}^{k_i+1}}}\\
&=\sum _{i=1}^{n}{\frac {(n-k_i-1)!\times (k_i+1)!}{n!}}\times C ^{k_i+2} _{n+1}\\
&=\sum _{i=1}^{n}{\frac {(n-k_1-1)!\times (k_i+1)!}{n!}\times {\frac {(n+1)!}{(n-k_i-1)!\times (k_i+2)!}}}\\
&=\sum _{i=1}^{n}{\frac {n+1}{k_i+2}}
\end{aligned}
$\quad $ 令 \(x_i=\sum _{j=1}^{n}{h[j]<h[i]}\),那么 $ k_i$ ,可以转化为 \(n+1-x_i\)
$\quad $ 设置一个桶记录一下各个高度人数,在循环的时候算出来 \(x_i\) 即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int cnt[N],sum,n;
double ans;
int main(){
	scanf("%d",&n);
	n++;
	for(int i=1;i<n;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}
	for(int i=1;i<=1000;i++)
		if(cnt[i])ans+=1.0*cnt[i]/(n-sum),sum+=cnt[i];
	printf("%.2lf",ans*n);
}
posted @ 2024-05-28 10:32  无敌の暗黑魔王  阅读(38)  评论(0编辑  收藏  举报