蓝书——218. 扑克牌

概率dp经典题目

f[a][b][c][d][x][y],黑桃a张,红桃b张,梅花c张,方块d张。大王小王状态x,y(等于0代表每抽到,等于1,2,3,4代表摸到四种花色)时,摸到满足题意的状态的期望张数。

下一张摸牌有6种情况:四种花色,大小王。dfs枚举递推即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef __int128 LL;
//typedef unsigned long long ull;
//#define F first
//#define S second
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
const ld PI=acos(-1);
const ld eps=1e-9;
//unordered_map<int,int>mp;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
//#define a(i,j) a[(i)*(m+2)+(j)]  //m是矩阵的列数
//pop_back()
const int seed=131;
const int M = 16;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y,int z){ee[++cnt].nxt=head[x],ee[cnt].to=y,ee[cnt].val=z,head[x]=cnt;}
*/
int  A,B,C,D;
double f[M][M][M][M][5][5];
double dfs(int a,int b,int c,int d,int x,int y)
{
	
	if(f[a][b][c][d][x][y]>1e-8)return f[a][b][c][d][x][y];
	if(a+(x==1)+(y==1)>=A&&b+(x==2)+(y==2)>=B&&c+(x==3)+(y==3)>=C&&d+(x==4)+(y==4)>=D)return 0; //边界
	double ans=1.0;//无论哪种情况都要再翻一张 
	int sum=a+b+c+d+(x!=0)+(y!=0);
	if(a<13)ans+=dfs(a+1,b,c,d,x,y)*(13-a)/(54-sum);//摸到黑桃 
	if(b<13)ans+=dfs(a,b+1,c,d,x,y)*(13-b)/(54-sum);//摸到红桃
	if(c<13)ans+=dfs(a,b,c+1,d,x,y)*(13-c)/(54-sum);//摸到梅花 
	if(d<13)ans+=dfs(a,b,c,d+1,x,y)*(13-d)/(54-sum);//摸到方块 
	double xi=1e9,di=1e9;
	if(x==0)//大王还在 摸到大王
	{
		for(int i=1;i<=4;i++)xi=min(xi,dfs(a,b,c,d,i,y)/(54-sum));
		ans+=xi;
	}
	if(y==0)//小王还在 摸到小王
	{
		for(int i=1;i<=4;i++)di=min(di,dfs(a,b,c,d,x,i)/(54-sum));
		ans+=di;
	}
	return f[a][b][c][d][x][y]=ans;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>A>>B>>C>>D;
  	if(max(A-13,0)+max(B-13,0)+max(C-13,0)+max(D-13,0)>2){
  		cout<<"-1.000"<<endl;
		return 0;
	}
	
	printf("%.3f\n",dfs(0,0,0,0,0,0));
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
扑克牌比大小是一个经典的游戏规则,也是很多人喜欢玩的一种游戏。在这里,我们将介绍如何用PHP实现扑克牌比大小的功能。 首先,我们需要定义扑克牌的大小顺序。一般来说,扑克牌的大小顺序为:2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A。其中,J表示“Jack”,Q表示“Queen”,K表示“King”,A表示“Ace”。 接下来,我们需要定义扑克牌的花色。扑克牌的花色一般有四种:黑桃(Spades)、红心(Hearts)、方块(Diamonds)和梅花(Clubs)。 有了扑克牌大小顺序和花色的定义,我们就可以开始实现比大小的功能了。具体实现方式如下: 1. 定义一组扑克牌,可以使用数组来表示,例如: ``` $poker = array( 'Spades-A', 'Spades-2', 'Spades-3', 'Spades-4', 'Spades-5', 'Spades-6', 'Spades-7', 'Spades-8', 'Spades-9', 'Spades-10', 'Spades-J', 'Spades-Q', 'Spades-K', 'Hearts-A', 'Hearts-2', 'Hearts-3', 'Hearts-4', 'Hearts-5', 'Hearts-6', 'Hearts-7', 'Hearts-8', 'Hearts-9', 'Hearts-10', 'Hearts-J', 'Hearts-Q', 'Hearts-K', 'Diamonds-A', 'Diamonds-2', 'Diamonds-3', 'Diamonds-4', 'Diamonds-5', 'Diamonds-6', 'Diamonds-7', 'Diamonds-8', 'Diamonds-9', 'Diamonds-10', 'Diamonds-J', 'Diamonds-Q', 'Diamonds-K', 'Clubs-A', 'Clubs-2', 'Clubs-3', 'Clubs-4', 'Clubs-5', 'Clubs-6', 'Clubs-7', 'Clubs-8', 'Clubs-9', 'Clubs-10', 'Clubs-J', 'Clubs-Q', 'Clubs-K' ); ``` 2. 随机抽取两张扑克牌,比较它们的大小。可以使用rand()函数来随机生成一个数字,然后用该数字获取对应的扑克牌,例如: ``` $card1 = $poker[rand(0, count($poker) - 1)]; $card2 = $poker[rand(0, count($poker) - 1)]; ``` 3. 比较两张扑克牌的大小。首先,我们需要将扑克牌的大小和花色分开。可以使用explode()函数来分割字符串,例如: ``` $card1_arr = explode('-', $card1); $card1_num = $card1_arr[1]; $card1_suit = $card1_arr[0]; ``` 4. 比较两张扑克牌的大小。按照扑克牌的大小顺序,依次比较两张牌的大小。如果两张牌的大小相同,则再比较它们的花色,花色较大的牌胜出。例如: ``` if ($card1_num == $card2_num) { if ($card1_suit == 'Spades' && $card2_suit != 'Spades') { echo $card1 . ' wins!'; } elseif ($card1_suit == 'Hearts' && ($card2_suit == 'Diamonds' || $card2_suit == 'Clubs')) { echo $card1 . ' wins!'; } elseif ($card1_suit == 'Diamonds' && $card2_suit == 'Clubs') { echo $card1 . ' wins!'; } else { echo $card2 . ' wins!'; } } elseif ($card1_num > $card2_num) { echo $card1 . ' wins!'; } else { echo $card2 . ' wins!'; } ``` 至此,我们就完成了用PHP实现扑克牌比大小的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值