LightOJ-1364 Expected Cards

期望dp+记忆化搜索

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int C,D,H,S;
double dp[17][17][17][17][5][5];
bool vis[17][17][17][17][5][5];
double dfs(int c,int d,int h,int s,int i,int j)
{
    int cc=c,dd=d,hh=h,ss=s;
    if(i==1) cc--;if(j==1) cc--;
    if(i==2) dd--;if(j==2) dd--;
    if(i==3) hh--;if(j==3) hh--;
    if(i==4) ss--;if(j==4) ss--;
    if(cc>13||dd>13||hh>13||ss>13) return 0.0;
    if(c>=C&&d>=D&&h>=H&&s>=S) return 0.0;
    if(vis[c][d][h][s][i][j]) return dp[c][d][h][s][i][j];
    vis[c][d][h][s][i][j]=true;
    double ans=0.0,t;
    int cnt=54-c-d-h-s;
    if(!i)
    {
        t=min(100.0,dfs(c+1,d,h,s,1,j));
        t=min(t,dfs(c,d+1,h,s,2,j));
        t=min(t,dfs(c,d,h+1,s,3,j));
        t=min(t,dfs(c,d,h,s+1,4,j));
        ans+=t;
    }
    if(!j)
    {
        t=min(100.0,dfs(c+1,d,h,s,i,1));
        t=min(t,dfs(c,d+1,h,s,i,2));
        t=min(t,dfs(c,d,h+1,s,i,3));
        t=min(t,dfs(c,d,h,s+1,i,4));
        ans+=t;
    }
    ans+=(13-cc)*dfs(c+1,d,h,s,i,j);
    ans+=(13-dd)*dfs(c,d+1,h,s,i,j);
    ans+=(13-hh)*dfs(c,d,h+1,s,i,j);
    ans+=(13-ss)*dfs(c,d,h,s+1,i,j);
    ans=ans/cnt+1.0;
    dp[c][d][h][s][i][j]=ans;
    return ans;
}
int main()
{
    int T,kase=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d",&C,&D,&H,&S);
        int num=0;
        num+=max(C-13,0);
        num+=max(D-13,0);
        num+=max(H-13,0);
        num+=max(S-13,0);
        printf("Case %d: ",++kase);
        memset(vis,false,sizeof(vis));
        if(num>2) printf("-1\n");
        else printf("%.6f\n",dfs(0,0,0,0,0,0));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wl16wzl/article/details/83004445