zoukankan      html  css  js  c++  java
  • codeforces gym 100357 H (DP 高精度)

    题目大意

      有r*s张扑克牌,数字从1到 r,每种数字有s种颜色。

      询问对于所有随机的d张牌,能选出c张组成顺子的概率和组成同花的概率

    解题分析

      对于组成顺子的概率,令dp[i][j][k]表示一共选出了i张牌,数字从1~j,最后有k张牌是顺子。对于每个数字进行考虑,有0~s种选法。要保证连续c张牌的顺子。

      对于组成同花的概率,令dp[i][j]表示一共选出了i张牌,颜色从1~j,。对于每种颜色进行考虑,有0~r种选法。要保证没有c张牌是相同颜色的。

      最后用高精度来输出答案。

    参考程序

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int N=30;
      5 
      6 class bign  
      7 {  
      8     public:
      9     enum {MAXN = 100};
     10     int len, s[MAXN];  
     11     void clean()  
     12     {  
     13         while(len > 1 && !s[len-1]) len--;  
     14     }
     15     bign ()  
     16     {  
     17         memset(s, 0, sizeof(s));  
     18         len = 1;  
     19     }  
     20     bign (int num) { *this = num; }  
     21     bign (long long num) { *this = num; }  
     22     bign (const char *num) { *this = num; }
     23     bign operator = (const long long num)  
     24     {  
     25         char s[MAXN];  
     26         sprintf(s, "%I64d", num);  
     27         *this = s;  
     28         return *this;  
     29     }    
     30     bign operator = (const int num)  
     31     {  
     32         char s[MAXN];  
     33         sprintf(s, "%d", num);  
     34         *this = s;  
     35         return *this;  
     36     }  
     37     bign operator = (const char *num)  
     38     {  
     39         for(int i = 0; num[i] == '0' && num[1]!=''; num++) ;  //去前导0  
     40         len = strlen(num);  
     41         for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';  
     42         return *this;  
     43     }  
     44     bign operator + (const bign &b) const //+  
     45     {  
     46         bign c;  
     47         c.len = 0;  
     48         for(int i = 0, g = 0; g || i < max(len, b.len); i++)  
     49         {  
     50             int x = g;  
     51             if(i < len) x += s[i];  
     52             if(i < b.len) x += b.s[i];  
     53             c.s[c.len++] = x % 10;  
     54             g = x / 10;  
     55         }  
     56         return c;  
     57     }  
     58     bign operator += (const bign &b)  
     59     {  
     60         *this = *this + b;  
     61         return *this;  
     62     }    
     63     bign operator * (const int x)
     64     {
     65         bign c;  
     66         int j=0; for (int y=x;y;y/=10,j++);
     67         c.len = len + j;          
     68         for(int i = 0; i < len; i++)  
     69             c.s[i]  = s[i] * x;
     70 
     71         for(int i = 0; i < c.len; i++)  
     72         {  
     73             c.s[i+1] += c.s[i]/10;  
     74             c.s[i] %= 10;  
     75         }
     76         c.clean();  
     77         return c;  
     78     }
     79     bign operator * (const bign &b) //*  
     80     {  
     81         bign c;  
     82         c.len = len + b.len;  
     83         for(int i = 0; i < len; i++)  
     84         {  
     85             for(int j = 0; j < b.len; j++)  
     86             {  
     87                 c.s[i+j] += s[i] * b.s[j];  
     88             }  
     89         }  
     90         for(int i = 0; i < c.len; i++)  
     91         {  
     92             c.s[i+1] += c.s[i]/10;  
     93             c.s[i] %= 10;  
     94         }  
     95         c.clean();  
     96         return c;  
     97     }  
     98     bign operator *= (const bign &b)  
     99     {  
    100         *this = *this * b;  
    101         return *this;  
    102     }    
    103     bign operator *= (const int x)  
    104     {  
    105         *this = *this * x;  
    106         return *this;  
    107     }  
    108     bign operator - (const bign &b)  
    109     {  
    110         bign c;  
    111         c.len = 0;  
    112         for(int i = 0, g = 0; i < len; i++)  
    113         {  
    114             int x = s[i] - g;  
    115             if(i < b.len) x -= b.s[i];  
    116             if(x >= 0) g = 0;  
    117             else  
    118             {  
    119                 g = 1;  
    120                 x += 10;  
    121             }  
    122             c.s[c.len++] = x;  
    123         }  
    124         c.clean();  
    125         return c;  
    126     }  
    127     bign operator -= (const bign &b)  
    128     {  
    129         *this = *this - b;  
    130         return *this;  
    131     }  
    132     bign operator / (const bign &b)  
    133     {  
    134         bign c, f = 0;  
    135         for(int i = len-1; i >= 0; i--)  
    136         {  
    137             f = f*10;  
    138             f.s[0] = s[i];  
    139             while(f >= b)  
    140             {  
    141                 f -= b;  
    142                 c.s[i]++;  
    143             }  
    144         }  
    145         c.len = len;  
    146         c.clean();  
    147         return c;  
    148     }  
    149     bign operator /= (const bign &b)  
    150     {  
    151         *this  = *this / b;  
    152         return *this;  
    153     }  
    154     bign operator % (const bign &b)  
    155     {  
    156         bign r = *this / b;  
    157         r = *this - r*b;  
    158         return r;  
    159     }  
    160     bign operator %= (const bign &b)  
    161     {  
    162         *this = *this % b;  
    163         return *this;  
    164     }  
    165     bool operator < (const bign &b)  
    166     {  
    167         if(len != b.len) return len < b.len;  
    168         for(int i = len-1; i >= 0; i--)  
    169         {  
    170             if(s[i] != b.s[i]) return s[i] < b.s[i];  
    171         }  
    172         return false;  
    173     }  
    174     bool operator > (const bign &b)  
    175     {  
    176         if(len != b.len) return len > b.len;  
    177         for(int i = len-1; i >= 0; i--)  
    178         {  
    179             if(s[i] != b.s[i]) return s[i] > b.s[i];  
    180         }  
    181         return false;  
    182     }  
    183     bool operator == (const bign &b)  
    184     {  
    185         return !(*this > b) && !(*this < b);  
    186     }  
    187     bool operator != (const bign &b)  
    188     {  
    189         return !(*this == b);  
    190     }  
    191     bool operator <= (const bign &b)  
    192     {  
    193         return *this < b || *this == b;  
    194     }  
    195     bool operator >= (const bign &b)  
    196     {  
    197         return *this > b || *this == b;  
    198     }  
    199     operator string() const  
    200     {  
    201         string res = "";  
    202         for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;  
    203         return res;  
    204     }  
    205     friend istream& operator >> (istream &in, bign &x)  
    206     {  
    207         string s;  
    208         in >> s;  
    209         x = s.c_str();  
    210         return in;  
    211     } 
    212     friend ostream& operator << (ostream &out, const bign &x)  
    213     {  
    214         out << string(x);
    215         return out;  
    216     } 
    217 };
    218 
    219 int r,s,d,c;
    220 int C[N][N];
    221 bign dp[N][N];
    222 bign f[N][N][N];
    223 
    224 bign calc_1(int n,int k)
    225 {
    226     bign tmp=1;
    227     for (int i=1;i<=k;i++) 
    228     {
    229         tmp=tmp*(n-(i-1));
    230         tmp=tmp/i;
    231     }
    232     return tmp;
    233 }
    234 
    235 bign gcd(bign x,bign y)
    236 {
    237     //return y>0?gcd(y,x % y):x;
    238     bign tmp;
    239     if (y>0) tmp=gcd(y,x % y); else tmp=x;
    240     return tmp;
    241 }
    242 
    243 int main()
    244 {
    245     freopen("poker.in","r",stdin);
    246     freopen("poker.out","w",stdout);
    247 
    248     for (int i=0;i<N;i++) C[i][0]=1;
    249     for (int i=1;i<N;i++)
    250         for (int j=1;j<=i;j++)
    251             C[i][j]=C[i-1][j]+C[i-1][j-1];
    252         
    253     cin.sync_with_stdio(0);
    254     while (cin>>r>>s>>d>>c)
    255     {
    256         if (!r && !s && !d && !c) break;
    257 
    258         memset(f,0,sizeof(f));
    259         for (int j=0;j<=r;j++) f[0][j][0]=1;
    260         for (int i=1;i<=d;i++)
    261             for (int j=1;j<=r;j++)
    262             {
    263                 for (int k=0;k<=min(i,c-1);k++) 
    264                     f[i][j][0]+=f[i][j-1][k];
    265                 for (int k=1;k<=min(j,c-1);k++)
    266                     for (int l=1;l<=min(i,s);l++)
    267                         f[i][j][k]+=f[i-l][j-1][k-1]*C[s][l];
    268             }
    269         bign ans=0;
    270         for (int k=0;k<=c-1;k++) ans+=f[d][r][k];
    271         bign a=calc_1(r*s,d),b=a-ans;
    272         cout<<b/gcd(a,b)<<"/"<<a/gcd(a,b)<<endl;
    273 
    274         memset(dp,0,sizeof(dp));
    275         for (int j=0;j<=s;j++) dp[0][j]=1;
    276         for (int i=1;i<=d;i++)
    277             for (int j=1;j<=s;j++)
    278                 for (int k=0;k<=min(i,c-1);k++)
    279                     dp[i][j]+=dp[i-k][j-1]*C[r][k];
    280         a=calc_1(r*s,d),b=a-dp[d][s];
    281         cout<<b/gcd(a,b)<<"/"<<a/gcd(a,b)<<endl<<endl;
    282     }
    283 }
    View Code
  • 相关阅读:
    UIViewcontroller生命周期方法
    runtime中的宏定义解释表
    opencv在Mac环境下的安装和配置
    Oracle导入导出
    Oracle触发器详解
    查找表的父表和子表
    Oracle创建表空间
    TRIGGER控制级联更新
    启动Oracle的bat文件
    PL(SQL)块
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/6798846.html
Copyright © 2011-2022 走看看