CF1267G Game Relics

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);
}
posted @ 2020-03-08 19:13  Shiina_Mashiro  阅读(407)  评论(0编辑  收藏  举报