codeforces 261B Maxim and Restaurant(期望DP)

题目链接:http://codeforces.com/problemset/problem/261/B

题意:有一个长度为P的桌子。有n个人,第i个人坐在桌子边的话需要占得长度为ai。n个人站成一队,从队头开始坐。到某个人时,桌子剩下的部分不够这个人坐的时候停止。这时,有x个人坐下。n!种排队的方式每种都有一个x值。求x的平均值。

思路:f[i][j][k]表示取j个数和为i以k作为分隔,即i再加上第k个数就会超。那么最后只要枚举k,然后i枚举[p+1-ak,p]即可。

 







double fac[55],f[55][55][55];

int a[55],n,p;





int main()

{

    int i,j,k,x=0;

    fac[0]=1;

    for(i=1;i<=50;i++) fac[i]=fac[i-1]*i;

    scanf("%d",&n);

    for(i=1;i<=n;i++) scanf("%d",&a[i]),x+=a[i];

    scanf("%d",&p);

    if(x<=p)

    {

        printf("%d\n",n);

        return 0;

    }

    for(i=1;i<=n;i++) f[0][0][i]=1;

    for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j)

    {

        for(k=n;k>=1;k--) for(x=p;x>=0&&x>=a[i];x--)

        {

            f[x][k][j]+=f[x-a[i]][k-1][j];

        }

    }

    double ans=0;

    for(i=1;i<=n;i++)

    {

        if(a[i]>p) a[i]=p+1;

        for(x=p+1-a[i];x<=p;x++) for(k=1;k<=n;k++)

        {

            ans+=f[x][k][i]*fac[k]*fac[n-k-1]*k;

        }

    }

    ans/=fac[n];

    printf("%.7lf\n",ans);

    return 0;

}

 

  

 

你可能感兴趣的:(codeforces)