LightOJ 1364 Expected Cards(概率+DP)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1364

题意:一副牌。依次在桌面上放牌。求放了四种花色的牌为C,D,H,S张时放的牌数的期望。大小王出现时必须将其指定为某种花色。指定时要使最后的期望最小。

思路:DP,记录大小王是不是已经被指定过了。









int c,num=0;

int C,D,H,S;

double f[14][14][14][14][5][5];



double DFS(int c,int d,int h,int s,int x1,int x2)

{

    double &ans=f[c][d][h][s][x1][x2];

    if(ans>-0.5) return ans;

    int q[5];

    int tot=c+d+h+s;

    if(!x1) tot++;

    if(!x2) tot++;

    q[1]=13-c;q[2]=13-d;q[3]=13-h;q[4]=13-s;

    q[x1]++;q[x2]++;

    if(q[1]>=C&&q[2]>=D&&q[3]>=H&&q[4]>=S) return ans=0;

    ans=0;

    if(c) ans+=1.0*c/tot*DFS(c-1,d,h,s,x1,x2);

    if(d) ans+=1.0*d/tot*DFS(c,d-1,h,s,x1,x2);

    if(h) ans+=1.0*h/tot*DFS(c,d,h-1,s,x1,x2);

    if(s) ans+=1.0*s/tot*DFS(c,d,h,s-1,x1,x2);

    int i;

    double t;

    if(!x1)

    {

        t=1e20;

        FOR1(i,4) t=min(t,DFS(c,d,h,s,i,x2));

        ans+=1.0/tot*t;

    }

    if(!x2)

    {

        t=1e20;

        FOR1(i,4) t=min(t,DFS(c,d,h,s,x1,i));

        ans+=1.0/tot*t;

    }

    ans+=1;

    return ans;

}



int main()

{

    RD(c);

    while(c--)

    {

        RD(C,D);

        RD(H,S);

        printf("Case %d: ",++num);

        int x=0;

        if(C>13) x+=C-13;

        if(D>13) x+=D-13;

        if(H>13) x+=H-13;

        if(S>13) x+=S-13;

        if(x>2)

        {

            puts("-1");

            continue;

        }

        clr(f,-1);

        printf("%.8lf\n",DFS(13,13,13,13,0,0));

    }

    return 0;

}

  

你可能感兴趣的:(expect)