题解 [Violet 5] 列队春游
然而题解都很详细,所以我只解释一步,就是第三步
于是我们将一个方案定义为只考虑 \(k\) 个大于等于当前小朋友的人,剩下的人先不计入方案数
于是(只计算当前小朋友及能挡住他的人)方案数是 \(A_n^{k+1}\)
我们将这样的方案称作「基础方案」,而一个最终方案是将其余小朋友插入当前序列中得到的
于是考虑钦定这个小朋友的位置,有 \(n-i+1\) 种可能(\(i\) 是视野范围)
然后要钦定这个小朋友前面 \(i-1\) 个位置不能有能挡住他的人,于是乘上 \(A_{n-i}^k\)
后面的就按照题解的方法拆式子即可
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 310
#define ll long long
#define fir first
#define sec second
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
double ans;
map<int, int> mp;
signed main()
{
n=read();
for (int i=1; i<=n; ++i) ++mp[read()];
int cnt=0;
for (auto it:mp) {
int k=n-cnt-1;
ans+=1.0*it.sec*(n+1)/(k+2);
cnt+=it.sec;
}
printf("%.2lf\n", ans);
return 0;
}