CSUOJ1206--Card game

如果我们可以求出两个人n张牌取k张的所有情况,问题就会变成一个简单的排列问题:A获胜的概率=A k张牌比B k张牌大的情况/总情况.然后我们可以用dp处理出n张牌中取k张牌的所有情况,dp[i][j][k]表示前i张牌中取j张牌构成k点的情况数,

状态转移:dp[i][j][k]=dp[i-1][j][k]+k>=a[i]?dp[i-1][j-1][k-a[i]]:0;

然后就是在计算概率时因为数比较大,必须用double,并且采取除两次的方法,避免总情况数过大导致溢出.

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

double dp[55][55][650];
int a[55],b[55];

int check(char ch)
{
      if(ch==‘A‘)  return 1;
      if(ch==‘X‘)  return 10;
      if(ch==‘J‘)   return 11;
      if(ch==‘Q‘)  return 12;
      if(ch==‘K‘)  return 13;
      return ch-‘0‘;
}

int main()
{
       int n,k,t;
       scanf("%d",&t);
       while(t--)
       {
               char str[3];
               double C=1;
               double f1[650],f2[650];
               int sum1=0,sum2=0;
               scanf("%d%d",&n,&k);
               for(int i=1;i<=k;i++)
                     C=C*(n-i+1)/i;
               for(int i=1;i<=n;i++)
               {
                     scanf("%s",str);
                     a[i]=check(str[0]);
                     sum1+=a[i];
               }
               for(int i=1;i<=n;i++)
               {
                     scanf("%s",str);
                     b[i]=check(str[0]);
                     sum2+=b[i];
               }
               memset(dp,0,sizeof(dp));
              for(int i=0;i<=n;i++)
                  dp[i][0][0]=1;
             for(int i=1;i<=n;i++)
                  for(int j=1;j<=i&&j<=k;j++)
                       for(int d=1;d<=sum1;d++)
                       {
                           if(d>=a[i])
                                dp[i][j][d]=dp[i-1][j][d]+dp[i-1][j-1][d-a[i]];
                           else
                                dp[i][j][d]=dp[i-1][j][d];
                        }
              for(int i=1;i<=sum1;i++)
                  f1[i]=1.0*dp[n][k][i]/C;
              memset(dp,0,sizeof(dp));
              for(int i=0;i<=n;i++)
                  dp[i][0][0]=1;
              for(int i=1;i<=n;i++)
                  for(int j=1;j<=i&&j<=k;j++)
                       for(int d=1;d<=sum2;d++)
                       {
                             if(d>=b[i])
                                  dp[i][j][d]=dp[i-1][j][d]+dp[i-1][j-1][d-b[i]];
                             else
                                  dp[i][j][d]=dp[i-1][j][d];
                        }
            f2[0]=0.0;
            for(int i=1;i<=sum1;i++)
            {
                  f2[i]=1.0*dp[n][k][i]/C;
                  f2[i]+=f2[i-1];
            }
            double  cnt=0;
            for(int i=1;i<=sum1;i++)
               cnt+=(double)f1[i]*f2[i-1];
            printf("%.6lf\n",1.0*cnt);
       }
  return 0;
}
时间: 2024-12-19 01:57:05

CSUOJ1206--Card game的相关文章

sdio card休眠处理 sdio card removed解决办法

最近调试几款sdio card suspend时都会出现sdio card removed,之后 要么死机要么模块不能正常工作,根本原因也就是休眠没有处理好. 昨天在博通网卡上终于找到了解决方法. 1:host端需要设置nonremovable,软件设置:mmc->caps |= MMC_CAP_NONREMOVABLE; 2:host端需要设置keep power,在sdio card suspend时 软件设 置:host->pm_flags | = MMC_PM_KEEP_POWER:

UESTC 31 饭卡(Card) --背包问题

背包问题. 思路:如果m<5,此时也不能消费,所以此时答案为m m>=5: 求出背包容量为m-5,买前n-1样便宜的菜(排个序)的最大价值(即最大消费,即消费完后剩余值最接近5)最后减去最大的那个菜的价格,就得到最小的余额. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using n

hdu 4336 Card Collector

Card Collector http://acm.hdu.edu.cn/showproblem.php?pid=4336 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Special Judge Problem Description In your childhood, do you crazy for collecting the beautiful cards in

Using Android Phone to recover SD card formatted with DD command under linux

1. Formatted a sd card with dd command under linux 2.insert the sd card into an android phone,certainly the card is not find and used.. 3 reset the android phone with format sd card option. 4.the sd card is ok!

Secrets To Getting Amazon gift card codes To Complete Tasks Quickly And Efficiently

Amazon gift card are not as easy to get if you do not know how to complet a survey . Amazon gift card are difficult and as hard to combact with the survey . So please do not hurry you should try the new method to get free amazon gift card codes . For

Identity Card(水题)

Identity Card Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2696    Accepted Submission(s): 1048 Problem Description Do you own an ID card?You must have a identity card number in your family'

hdu 5159 Card (期望)

Problem Description There are x cards on the desk, they are numbered from 1 to x. The score of the card which is numbered i(1<=i<=x) is i. Every round BieBie picks one card out of the x cards,then puts it back. He does the same operation for b round

HDU 5159 Card( 计数 期望 )

Card Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 191    Accepted Submission(s): 52Special Judge Problem Description There are x cards on the desk, they are numbered from 1 to x. The score o

Y460/Y470 Nvidia optirum solution : switch off the nvidia card and solve screen flash problem

i have such a long time fall in love with ubuntu , but i found it's much unconfortable for me with a lenovo y460n , that owning a intel display card and a Nvidia GT425M card . once i install ubuntu (from 10.04 , 12.04 , 14.04 , so many versions i had

JAVA card 应用开发 JCOP的调试方法

本文讲述如何在仿真环境下,调试JAVA card 的APPLET. 通过JCOP在Eclipse进行仿真调试,启动JCOP调试器,我们可以看到如下图: 要仿真调试,就是在命令输入框里面输入JCOP相关的指令,通过阅读JCOP的帮助文档,我们看到JCOP提供的命令不算繁多,大约40个. 下面我挑选常用的几个来说明: 1.      复位卡片:"/atr",如果不加任何参数,表示立即复位. 2.      发送指令:"/send",这是最直观的调试指令.可以逐个指令发送