TYVJ P2002 扑克牌

Posted SilverNebula

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TYVJ P2002 扑克牌相关的知识,希望对你有一定的参考价值。

 

背景

Admin生日那天,Rainbow来找Admin玩扑克牌……
玩着玩着Rainbow觉得太没意思了,于是决定给Admin一个考验~~~

描述

Rainbow把一副扑克牌(54张)随机洗开,倒扣着放成一摞。然后Admin从上往下依次翻开每张牌,每翻开一张黑桃、红桃、梅花或者方块,就把它放到对应花色的堆里去。
Rainbow想问问Admin,得到A张黑桃、B张红桃、C张梅花、D张方块需要翻开的牌的张数的期望值E是多少?
特殊地,如果翻开的牌是大王或者小王,Admin将会把它作为某种花色的牌放入对应堆中,使得放入之后E的值尽可能小。
由于Admin和Rainbow还在玩扑克,所以这个程序就交给你来写了~

输入格式

输入仅由一行,包含四个用空格隔开的整数,A,B,C,D。

输出格式

输出需要翻开的牌数的期望值E,四舍五入保留3位小数。
如果不可能达到输入的状态,输出-1.000。

测试样例1

输入

样例输入1
1 2 3 4

样例输入2
15 15 15 15

输出

样例输出1
16.393

样例输出2
-1.000

备注

对于100%的数据,0<=A,B,C,D<=15

lydrainbowcat - "Admin生日"杯NOIP模拟赛 第三题
Blog: www.lydrainbowcat.tk  Email: [email protected]

 

 

决策挺复杂的。

现在不想写解析,日后补。

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=15;
 9 double f[mxn][mxn][mxn][mxn][5][5];
10 bool vis[mxn][mxn][mxn][mxn][5][5];
11 int x1,x2,x3,x4;
12 double dp(int a,int b,int c,int d,int e,int g){
13     if(vis[a][b][c][d][e][g])return f[a][b][c][d][e][g];
14     int i;
15 
16     if(((a+(e==0)+(g==0))>=x1) && ((b+(e==1)+(g==1))>=x2) && ((c+(e==2)+(g==2))>=x3) && ((d+(e==3)+(g==3))>=x4))
17         return f[a][b][c][d][e][g]=0;
18     int sum=a+b+c+d+(e!=4)+(g!=4);
19     double tmp=1;
20     //普通 
21     if(a<13)tmp+=dp(a+1,b,c,d,e,g)*(13-a)/(54-sum);
22     if(b<13)tmp+=dp(a,b+1,c,d,e,g)*(13-b)/(54-sum);
23     if(c<13)tmp+=dp(a,b,c+1,d,e,g)*(13-c)/(54-sum);
24     if(d<13)tmp+=dp(a,b,c,d+1,e,g)*(13-d)/(54-sum);
25     //
26     double es;
27     if(e==4){
28         es=100;
29         for(i=0;i<=3;i++) es=min(dp(a,b,c,d,i,g)/(54-sum),es);
30         tmp+=es;
31     }
32     if(g==4){
33         es=100;
34         for(i=0;i<=3;i++) es=min(dp(a,b,c,d,e,i)/(54-sum),es);
35         tmp+=es;
36     }
37     
38     vis[a][b][c][d][e][g]=1;
39     return f[a][b][c][d][e][g]=tmp;
40 }
41 int main(){
42     memset(vis,0,sizeof(vis));
43     int a,b,c,d;
44     scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
45     double ans=dp(0,0,0,0,4,4);
46     if(ans>54)ans=-1;
47     printf("%.3lf\n",ans);
48     return 0;
49 }

 

以上是关于TYVJ P2002 扑克牌的主要内容,如果未能解决你的问题,请参考以下文章

Tyvj 2002 扑克牌

TYVJ2002 扑克牌

TYVJ4239 [NOIP2015提高组DayT3]斗地主

P2002 消息扩散

P2002 消息扩散

题解 P2002 消息扩散