题目大意

  有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张牌是相同颜色的。

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

参考程序

 #include <bits/stdc++.h>
using namespace std; const int N=; class bign
{
public:
enum {MAXN = };
int len, s[MAXN];
void clean()
{
while(len > && !s[len-]) len--;
}
bign ()
{
memset(s, , sizeof(s));
len = ;
}
bign (int num) { *this = num; }
bign (long long num) { *this = num; }
bign (const char *num) { *this = num; }
bign operator = (const long long num)
{
char s[MAXN];
sprintf(s, "%I64d", num);
*this = s;
return *this;
}
bign operator = (const int num)
{
char s[MAXN];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bign operator = (const char *num)
{
for(int i = ; num[i] == '' && num[]!='\0'; num++) ; //去前导0
len = strlen(num);
for(int i = ; i < len; i++) s[i] = num[len-i-] - '';
return *this;
}
bign operator + (const bign &b) const //+
{
bign c;
c.len = ;
for(int i = , g = ; g || i < max(len, b.len); i++)
{
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % ;
g = x / ;
}
return c;
}
bign operator += (const bign &b)
{
*this = *this + b;
return *this;
}
bign operator * (const int x)
{
bign c;
int j=; for (int y=x;y;y/=,j++);
c.len = len + j;
for(int i = ; i < len; i++)
c.s[i] = s[i] * x; for(int i = ; i < c.len; i++)
{
c.s[i+] += c.s[i]/;
c.s[i] %= ;
}
c.clean();
return c;
}
bign operator * (const bign &b) //*
{
bign c;
c.len = len + b.len;
for(int i = ; i < len; i++)
{
for(int j = ; j < b.len; j++)
{
c.s[i+j] += s[i] * b.s[j];
}
}
for(int i = ; i < c.len; i++)
{
c.s[i+] += c.s[i]/;
c.s[i] %= ;
}
c.clean();
return c;
}
bign operator *= (const bign &b)
{
*this = *this * b;
return *this;
}
bign operator *= (const int x)
{
*this = *this * x;
return *this;
}
bign operator - (const bign &b)
{
bign c;
c.len = ;
for(int i = , g = ; i < len; i++)
{
int x = s[i] - g;
if(i < b.len) x -= b.s[i];
if(x >= ) g = ;
else
{
g = ;
x += ;
}
c.s[c.len++] = x;
}
c.clean();
return c;
}
bign operator -= (const bign &b)
{
*this = *this - b;
return *this;
}
bign operator / (const bign &b)
{
bign c, f = ;
for(int i = len-; i >= ; i--)
{
f = f*;
f.s[] = s[i];
while(f >= b)
{
f -= b;
c.s[i]++;
}
}
c.len = len;
c.clean();
return c;
}
bign operator /= (const bign &b)
{
*this = *this / b;
return *this;
}
bign operator % (const bign &b)
{
bign r = *this / b;
r = *this - r*b;
return r;
}
bign operator %= (const bign &b)
{
*this = *this % b;
return *this;
}
bool operator < (const bign &b)
{
if(len != b.len) return len < b.len;
for(int i = len-; i >= ; i--)
{
if(s[i] != b.s[i]) return s[i] < b.s[i];
}
return false;
}
bool operator > (const bign &b)
{
if(len != b.len) return len > b.len;
for(int i = len-; i >= ; i--)
{
if(s[i] != b.s[i]) return s[i] > b.s[i];
}
return false;
}
bool operator == (const bign &b)
{
return !(*this > b) && !(*this < b);
}
bool operator != (const bign &b)
{
return !(*this == b);
}
bool operator <= (const bign &b)
{
return *this < b || *this == b;
}
bool operator >= (const bign &b)
{
return *this > b || *this == b;
}
operator string() const
{
string res = "";
for(int i = ; i < len; i++) res = char(s[i]+'') + res;
return res;
}
friend istream& operator >> (istream &in, bign &x)
{
string s;
in >> s;
x = s.c_str();
return in;
}
friend ostream& operator << (ostream &out, const bign &x)
{
out << string(x);
return out;
}
}; int r,s,d,c;
int C[N][N];
bign dp[N][N];
bign f[N][N][N]; bign calc_1(int n,int k)
{
bign tmp=;
for (int i=;i<=k;i++)
{
tmp=tmp*(n-(i-));
tmp=tmp/i;
}
return tmp;
} bign gcd(bign x,bign y)
{
//return y>0?gcd(y,x % y):x;
bign tmp;
if (y>) tmp=gcd(y,x % y); else tmp=x;
return tmp;
} int main()
{
freopen("poker.in","r",stdin);
freopen("poker.out","w",stdout); for (int i=;i<N;i++) C[i][]=;
for (int i=;i<N;i++)
for (int j=;j<=i;j++)
C[i][j]=C[i-][j]+C[i-][j-]; cin.sync_with_stdio();
while (cin>>r>>s>>d>>c)
{
if (!r && !s && !d && !c) break; memset(f,,sizeof(f));
for (int j=;j<=r;j++) f[][j][]=;
for (int i=;i<=d;i++)
for (int j=;j<=r;j++)
{
for (int k=;k<=min(i,c-);k++)
f[i][j][]+=f[i][j-][k];
for (int k=;k<=min(j,c-);k++)
for (int l=;l<=min(i,s);l++)
f[i][j][k]+=f[i-l][j-][k-]*C[s][l];
}
bign ans=;
for (int k=;k<=c-;k++) ans+=f[d][r][k];
bign a=calc_1(r*s,d),b=a-ans;
cout<<b/gcd(a,b)<<"/"<<a/gcd(a,b)<<endl; memset(dp,,sizeof(dp));
for (int j=;j<=s;j++) dp[][j]=;
for (int i=;i<=d;i++)
for (int j=;j<=s;j++)
for (int k=;k<=min(i,c-);k++)
dp[i][j]+=dp[i-k][j-]*C[r][k];
a=calc_1(r*s,d),b=a-dp[d][s];
cout<<b/gcd(a,b)<<"/"<<a/gcd(a,b)<<endl<<endl;
}
}

codeforces gym 100357 H (DP 高精度)的更多相关文章

  1. codeforces Gym 100187H H. Mysterious Photos 水题

    H. Mysterious Photos Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/p ...

  2. codeforces Gym 100500H H. ICPC Quest 水题

    Problem H. ICPC QuestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/a ...

  3. Codeforces Gym 100114 H. Milestones 离线树状数组

    H. Milestones Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descripti ...

  4. Codeforces Gym 100425H H - Football Bets 构造

    H - Football BetsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...

  5. codeforces gym 100357 K (表达式 模拟)

    题目大意 将一个含有+,-,^,()的表达式按照运算顺序转换成树状的形式. 解题分析 用递归的方式来处理表达式,首先直接去掉两边的括号(如果不止一对全部去光),然后找出不在括号内且优先级最低的符号.如 ...

  6. codeforces gym 100357 I (费用流)

    题目大意 给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1. 解题分析 将每个变量拆成三个点x,y,z. y表示对应的正变量,z表示对应的 ...

  7. codeforces gym 100357 J (网络流)

    题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...

  8. codeforces gym 100286 H - Hell on the Markets (贪心算法)

    题目链接 题意:n个数分别为a[i],问是否存在一组对应的b[i],b[i]=1 || b[i]=-1,使得ai*bi的n项和为0. 题解: 先证明一个结论吧,对于1≤ai≤i+1,前面ai个数一定可 ...

  9. Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】

     2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...

随机推荐

  1. akka监控框架设计

    本博客介绍一种AOP.无侵入的akka监控方案,方便大家在生产使用akka的过程中对akka进行监控. 对于自身javaer来说,AOP三个字母基本就解释清楚了akka监控框架的原理.哈哈哈,不过我这 ...

  2. 【计蒜客习题】两仪剑法(gcd)

    两仪剑法是武当派武功的高级功夫,且必须 2 个人配合使用威力才大.同时该剑法招数变化太快.太多.设武当弟子甲招数变化周期为 n,武当弟子乙招数变化周期为 m,两弟子同时使用该剑法,当 2 人恰好同时达 ...

  3. Rabin_Karp(hash) HDOJ 1711 Number Sequence

    题目传送门 /* Rabin_Karp:虽说用KMP更好,但是RK算法好理解.简单说一下RK算法的原理:首先把模式串的哈希值算出来, 在文本串里不断更新模式串的长度的哈希值,若相等,则找到了,否则整个 ...

  4. 378 Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素

    给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素.请注意,它是排序后的第k小元素,而不是第k个元素.示例:matrix = [   [ 1,  5,  9],   [ ...

  5. Spring Boot (33) 分布式锁

    上一篇中使用的Guava Cache,如果在集群中就不可以用了,需要借助Redis.Zookeeper之类的中间件实现分布式锁. 导入依赖 在pom.xml中需要添加的依赖包:stater-web.s ...

  6. VS中设置xml智能提示

    1.第一步:将xsd文件复制到VS的安装目录下 默认安装目录为:C:\Program Files (x86)\Microsoft Visual Studio 12.0\Xml\Schemas 2.第二 ...

  7. python自动化--接口请求及封装

    基于http协议,最常用的是GET和POST两种方法. 接口文档需要包含哪些信息: 接口名称接口功能接口地址支持格式 json/xml请求方式请求示例请求参数(是否必填.数据类型.传递参数格式)返回参 ...

  8. 脚手架工具搭建VUE应用

    首先需要安装node.js,然后安装CLI工具. vue init webpack vue-lesson2 使用element组件的话,需要用到如下命令: cd vue-lesson2 vue add ...

  9. Java基础(八)--String(源码)、StringBuffer、StringBuilder

    String源码:基于jdk1.8 public final class String implements Serializable, Comparable<String>, CharS ...

  10. 07Oracle Database 数据表

    Oracle Database 数据表 DDL 数据定义语言 -  建立数据库对象 create /alter/ drop/ truncate 创建表 Create table table_name( ...