首页 > 其他分享 >218. 扑克牌

218. 扑克牌

时间:2022-12-06 20:22:13浏览次数:57  
标签:return 扑克牌 int sum 218 Admin define

题目链接

218. 扑克牌

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

数据范围

\(0 \le A,B,C,D \le 15\)

输入样例:

1 2 3 4

输出样例:

16.393

解题思路

概率dp

  • 状态表示:\(f[a][b][c][d][x][y]\) 表示当前翻开 \(a\) 张黑桃,\(b\) 红桃,\(c\) 张梅花,\(d\) 张方块,且小王的状态为 \(x\)(\(x=0\) 表示选择黑桃,\(x=1\) 表示选择红桃,\(x=2\) 表示选择梅花,\(x=3\) 表示选择方块,\(x=4\) 表示未选中,大王同理),大王的状态为 \(y\) 的期望翻牌张数

  • 状态计算:这时还剩下的牌数为 \(sum=54-a-b-c-d-(x!=4)-(y!=4)\),这时再选中黑桃、红桃、梅花、方块的概率分别为 \(\frac{13-a}{sum}、\frac{13-b}{sum}、\frac{13-c}{sum}、\frac{13-d}{sum}\),相对应的状态转移,再判断这时的 \(x\) 和 \(y\) 的状态是否使用,如果未使用的话,选择一个期望长度最小的状态转移

  • 时间复杂度:\(O(13^4\times 5^2)\)

代码

// Problem: 扑克牌
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/220/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=15,inf=0x3f3f3f3f;
int A,B,C,D;
double f[N][N][N][N][5][5];
double dp(int a,int b,int c,int d,int x,int y)
{
	double &res=f[a][b][c][d][x][y];
	if(res>=0)return res;
	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)return res=0;
	int sum=54-a-b-c-d-(x!=4)-(y!=4);
	if(sum<=0)return res=inf;
	res=0;
	if(a<13)res+=(dp(a+1,b,c,d,x,y)+1)*(13-a)/sum;
	if(b<13)res+=(dp(a,b+1,c,d,x,y)+1)*(13-b)/sum;
	if(c<13)res+=(dp(a,b,c+1,d,x,y)+1)*(13-c)/sum;
	if(d<13)res+=(dp(a,b,c,d+1,x,y)+1)*(13-d)/sum;
	if(x==4)
	{
		double t=inf;
		t=min(t,dp(a,b,c,d,0,y));
		t=min(t,dp(a,b,c,d,1,y));
		t=min(t,dp(a,b,c,d,2,y));
		t=min(t,dp(a,b,c,d,3,y));
		res+=(t+1)/sum;
	}
	if(y==4)
	{
		double t=inf;
		t=min(t,dp(a,b,c,d,x,0));
		t=min(t,dp(a,b,c,d,x,1));
		t=min(t,dp(a,b,c,d,x,2));
		t=min(t,dp(a,b,c,d,x,3));
		res+=(t+1)/sum;
	}
	return res;
}
int main()
{
    scanf("%d%d%d%d",&A,&B,&C,&D);
    memset(f,-0x3f,sizeof f);
    double res=dp(0,0,0,0,4,4);
    if(res>inf/2)puts("-1.000");
    else
    	printf("%.3lf",res);
    return 0;
}

标签:return,扑克牌,int,sum,218,Admin,define
From: https://www.cnblogs.com/zyyun/p/16960404.html

相关文章

  • 2184. 餐巾计划问题
    题目链接2184.餐巾计划问题一个餐厅在相继的\(N\)天里,每天需用的餐巾数不尽相同。假设第\(i\)天需要\(r_i\)块餐巾\((i=1,2,…,N)\)。餐厅可以购买新的餐巾,每......
  • 2180. 最长递增子序列问题
    题目链接2180.最长递增子序列问题给定正整数序列\(x_1,\cdots,x_n\)。计算其最长递增子序列的长度\(s\)。计算从给定的序列中最多可取出多少个长度为\(s\)的......
  • 2187. 星际转移问题
    题目链接2187.星际转移问题由于人类对自然资源的消耗,人们意识到大约在\(2300\)年之后,地球就不能再居住了。于是在月球上建立了新的绿地,以便在需要时移民。令人意想......
  • java实现扑克牌游戏(洗牌,发牌,排序)
    packagepoker.bean;importlombok.AllArgsConstructor;importlombok.Getter;importlombok.NoArgsConstructor;importlombok.Setter;importjava.lang.annotatio......
  • 2189. 有源汇上下界最大流
    题目链接2189.有源汇上下界最大流给定一个包含\(n\)个点\(m\)条边的有向图,每条边都有一个流量下界和流量上界。给定源点\(S\)和汇点\(T\),求源点到汇点的最大流......
  • vue2+ts 设计一个扑克牌比大小的游戏
    首先         ......
  • java静态代码块之扑克牌
    静态代码块生成54张扑克牌 packagecn.edu.dcxy;importjava.util.ArrayList;publicclassStaticCards{publicstaticArrayList<String>cards=newArra......
  • UVa 12186 工人的请愿书
    详见紫书P444题目输入:员工数n百分比T员工1的直属上司员工2的直属上司...员工n的直属上司310000035000014600011222575757500输出......
  • 施耐德PLC TM218如何实现远程上传下载程序?
    施耐德TM218支持IEC61131-3标准的六种编程语言,具备模块化、结构紧凑、功能全面等特点,在工业控制领域应用广泛,是市场上常见的产品之一,性价比较高。因此,对于采购施耐德PLC的企......
  • 每日算法题之扑克牌顺子
    JZ61扑克牌顺子描述现在有2副扑克牌,从扑克牌中随机五张扑克牌,我们需要来判断一下是不是顺子。有如下规则:1.A为1,J为11,Q为12,K为13,A不能视为142.大、小王为0,0可以看......