zoukankan      html  css  js  c++  java
  • Tyvj 2002 扑克牌

    P2002 扑克牌
    时间: 1000ms / 空间: 131072KiB / Java类名: Main

    背景

    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: lyd@tyvj.cn
     
    Solution
    我又把题目看错了ToT
    因为翻到大小王的时候,比较特殊,需要知道之后的答案,所以可以用记忆化搜索
    讲道理,dp过程中不存在无解的情况,但是由于翻到大小王的时候要找一种期望最小的情况,所以会出现无解的情况,这是不能取的,所以要返回inf
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    using namespace std;
    int A,B,C,D,inf=100000000;
    double f[15][15][15][15][5][5]; 
    int read()
    {
    	int ans=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
    	return ans*f;
    }
    bool ok(int a,int b,int c,int d,int w1,int w2)
    {
    	if(w1==1) a++;
    	if(w1==2) b++;
    	if(w1==3) c++;
    	if(w1==4) d++;
    	if(w2==1) a++;
    	if(w2==2) b++;
    	if(w2==3) c++;
    	if(w2==4) d++;
    	if(a<A||b<B||c<C||d<D)
    	  return 0;
    	else return 1;
    }
    double dp(int a,int b,int c,int d,int w1,int w2)
    {
    	double ans=0,n,mi;
    	if(f[a][b][c][d][w1][w2]!=-1)
    	  return f[a][b][c][d][w1][w2];
    	n=a+b+c+d;
    	if(w1) n++;
    	if(w2) n++;
    	if(ok(a,b,c,d,w1,w2))
    	  return 1.0*n;
    	if(n>=54) return inf;         //////////////////////
    	if(a+1<=13)
    	  ans+=(double)(13-a)*1.0/(54-n)*dp(a+1,b,c,d,w1,w2);        //强转
    	if(b+1<=13)
    	  ans+=(double)(13-b)*1.0/(54-n)*dp(a,b+1,c,d,w1,w2);
    	if(c+1<=13)
    	  ans+=(double)(13-c)*1.0/(54-n)*dp(a,b,c+1,d,w1,w2);
    	if(d+1<=13)
    	  ans+=(double)(13-d)*1.0/(54-n)*dp(a,b,c,d+1,w1,w2);
    	if(!w1)
    	{
    		mi=100000000;
    		for(int i=1;i<=4;i++) 
    	      mi=min(mi,dp(a,b,c,d,i,w2));
    	    ans+=mi/(54-n);
    	}
    	if(!w2)
    	{
    		mi=100000000;
    		for(int i=1;i<=4;i++) 
    	      mi=min(mi,dp(a,b,c,d,w1,i));
    	    ans+=mi/(54-n);
    	}
    	return f[a][b][c][d][w1][w2]=ans;
    }
    int main()
    {
    	int mo=0;
    	for(int a=0;a<=13;a++)
    	  for(int b=0;b<=13;b++)
    	    for(int c=0;c<=13;c++)
    	      for(int d=0;d<=13;d++)
    	        for(int w1=0;w1<=4;w1++)
    	          for(int w2=0;w2<=4;w2++)
    	            f[a][b][c][d][w1][w2]=-1;
    	scanf("%d%d%d%d",&A,&B,&C,&D);
    	if(A>13) mo+=A-13;
    	if(B>13) mo+=B-13;
    	if(C>13) mo+=C-13;
    	if(D>13) mo+=D-13;
    	if(mo>2)
    	{
    		printf("-1.000");
    		return 0;
    	}
    	double res=dp(0,0,0,0,0,0);
        printf("%.3lf",res);
    	return 0;
    }
  • 相关阅读:
    CSS text-indent 属性
    从零开始搭建一个简单的基于webpack的vue开发环境
    mui is not defined
    vue项目中引入mui.poppicker.js文件时报错“Uncaught ReferenceError: mui is not defined”
    vue-cli创建的项目中引入第三方库报错'caller', 'calle', and 'arguments' properties may not be...
    微信小程序点击顶部导航栏切换样式
    js学习笔记-日期对象
    setTimeout()和setInterval()的用法及区别
    Ubuntu 14.04 下安装redis后运行redis-cli 报出redis Connection refused错误【已解决】
    Ubuntu start:未知任务:mysql
  • 原文地址:https://www.cnblogs.com/charlotte-o/p/7692552.html
Copyright © 2011-2022 走看看