UVA12369 Cards 题解

题目传送门

前置知识

记忆化搜索

解法

本题中的得到是指目前的牌中包含所要求的牌,而不是目前的牌中恰好是所要求的牌。

\(f_{a,b,c,d,x,y}\) 表示已经抽了 \(a\) 张黑桃,\(b\) 张红桃,\(c\) 张梅花,\(d\) 张方块,大王/小王的使用状态为 \(x/y\) 时的期望张数。具体地,\(x/y=0 \sim 3\) 分别表示大王/小王视为黑桃、红桃、梅花、方块,\(x/y=4\) 表示未使用大王/小王。

状态转移方程为 \(f_{a,b,c,d,x,y}=1+\frac{13-a}{54-a-b-c-d-(x \ne 4)-(y \ne 4)} \times f_{a+1,b,c,d,x,y}+\frac{13-b}{54-a-b-c-d-(x \ne 4)-(y \ne 4)} \times f_{a,b+1,c,d,x,y}+\frac{13-c}{54-a-b-c-d-(x \ne 4)-(y \ne 4)} \times f_{a,b,c+1,d,x,y}+\frac{13-d}{54-a-b-c-d-(x \ne 4)-(y \ne 4)} \times f_{a,b,c,d+1,x,y}+\frac{[x=4]}{54-a-b-c-d-(x \ne 4)-(y \ne 4)} \times \min\limits_{x'=0}^{3} \{ f_{a,b,c,d,x',y} \}+\frac{[y=4]}{54-a-b-c-d-(x \ne 4)-(y \ne 4)} \times \min\limits_{y'=0}^{3} \{ f_{a,b,c,d,x,y'} \}\),需要注意边界处理。

记忆化搜索时维护即可。

最终,有 \(f_{0,0,0,0,4,4}\) 即为所求。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
int A,B,C,D;
double f[20][20][20][20][8][8];
bool vis[20][20][20][20][8][8];
double dfs(int a,int b,int c,int d,int x,int y)
{
    if(vis[a][b][c][d][x][y]==false)
    {
        vis[a][b][c][d][x][y]=true;
        int sum=a+b+c+d+(x!=4)+(y!=4);
        double minn;
        if(a>13||b>13||c>13||d>13||sum>54)
        {
            f[a][b][c][d][x][y]=0x7f7f7f7f;
        }
        else
        {
            if(a+(x==0)+(y==0)>=A&&b+(x==1)+(y==1)>=B&&c+(x==2)+(y==2)>=C&&d+(x==3)+(y==3)>=D)
            {
                f[a][b][c][d][x][y]=0;
            }
            else
            {
                f[a][b][c][d][x][y]=1+1.0*(13-a)/(54-sum)*dfs(a+1,b,c,d,x,y)
                                     +1.0*(13-b)/(54-sum)*dfs(a,b+1,c,d,x,y)
                                     +1.0*(13-c)/(54-sum)*dfs(a,b,c+1,d,x,y)
                                     +1.0*(13-d)/(54-sum)*dfs(a,b,c,d+1,x,y);
                if(x==4)
                {
                    minn=0x7f7f7f7f;
                    for(int i=0;i<=3;i++)
                    {
                        minn=min(minn,dfs(a,b,c,d,i,y));
                    }
                    f[a][b][c][d][x][y]+=1.0/(54-sum)*minn;
                }
                if(y==4)
                {
                    minn=0x7f7f7f7f;
                    for(int i=0;i<=3;i++)
                    {
                        minn=min(minn,dfs(a,b,c,d,x,i));
                    }
                    f[a][b][c][d][x][y]+=1.0/(54-sum)*minn;
                }
            }
        }
    }
    return f[a][b][c][d][x][y];
}
int main()
{
    int t,i;
    cin>>t;
    for(i=1;i<=t;i++)
    {
        cin>>A>>B>>C>>D;
        memset(f,0,sizeof(f));
        memset(vis,0,sizeof(vis));
        double ans=dfs(0,0,0,0,4,4);
        cout<<"Case "<<i<<": ";
        if(ans<=54)
        {
            printf("%.3lf\n",ans);
        }
        else
        {
            cout<<"-1.000"<<endl;
        }
    }
    return 0;
}
posted @ 2024-06-28 14:10  hzoi_Shadow  阅读(11)  评论(0编辑  收藏  举报
扩大
缩小