Link
首先显然是先抽卡,抽到一定时间之后直接全买保底。
假如在某个时刻,剩下(j)个物品,总价值为(k)。
此时进行抽卡直到抽中了一个未买到的物品,就相当于花((frac nj-1)frac x2)的钱买一个(frac kj)的物品。
我们可以依此判断在一个局面下应该抽卡还是买保底。
设(f_{j,k})表示到达还剩(j)个物品,总价值为(k)这一局面的概率,这可以用背包求出。然后对每种局面判断策略并计算对答案的贡献即可。
#include<cstdio>
#include<algorithm>
using db=double;
db f[107][10007];int a[107];
int main()
{
int n,x,sum=0;db ans=0;
scanf("%d%d",&n,&x),f[0][0]=1;
for(int i=1;i<=n;++i) scanf("%d",a+i),sum+=a[i];
for(int i=1;i<=n;++i) for(int j=i;j;--j) for(int k=a[i];k<=sum;++k) f[j][k]+=f[j-1][k-a[i]]*j/(n-j+1);
for(int i=1;i<=n;++i) for(int j=1;j<=sum;++j) ans+=f[i][j]*std::min((n+i)*x,j*2)/i;
printf("%.10lf",ans/2);
}