HDU 5194 DZY Loves Balls

Problem Description
There are n black balls and m white balls in the big box.

Now, DZY starts to randomly pick out the balls one by one. It forms a sequence S. If at the i-th operation, DZY takes out the black ball, Si=1, otherwise Si=0.

DZY wants to know the expected times that '01' occurs in S.
 

Input
The input consists several test cases. (TestCase150)

The first line contains two integers, nm(1n,m12)
 

Output
For each case, output the corresponding result, the format is p/q(p and q are coprime)
 

Sample Input
1 1 2 3
 

Sample Output
1/2 6/5
Hint
Case 1: S='01' or S='10', so the expected times = 1/2 = 1/2 Case 2: S='00011' or S='00101' or S='00110' or S='01001' or S='01010' or S='01100' or S='10001' or S='10010' or S='10100' or S='11000', so the expected times = (1+2+1+2+2+1+1+1+1+0)/10 = 12/10 = 6/5

考虑期望的可加性。第i(1i<n+m)个位置上出现0,第i+1个位置上出现1的概率是mn+m×nn+m1,那么答案自然就是i=1n+m1mn+m×nn+m1=nmn+m
如果你不能马上想到上述的简便的方法,也可以选择暴力枚举所有01串,也是可以AC的。最后一步你需要再计算一下gcd,十分简便。
强大的题解,可惜本人是想不到这样的,自己dp玩玩。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstdlib>
using namespace std;
const int maxn = 20;
int n, m, T, f[maxn][maxn][4], tot;

int gcd(int x, int y)
{
    if (x % y != 0) return gcd(y, x%y);
    return y;
}

int main()
{
    while (scanf("%d%d", &n, &m) != EOF)
    {
        memset(f, 0, sizeof(f));
        for (int i = 1; i <= max(n, m); i++) f[0][i][0] = f[i][0][1] = 1;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                if (i + j)
                {
                    f[i][j][0] = f[i][j - 1][0] + f[i][j - 1][1];
                    f[i][j][2] = f[i][j - 1][2] + f[i][j - 1][3];
                    f[i][j][1] = f[i - 1][j][0] + f[i - 1][j][1];
                    f[i][j][3] = f[i - 1][j][2] + f[i - 1][j][3] + f[i - 1][j][0];
                }
        for (int i = n + 1, j = tot = 1; i <= n + m; i++)
        {
            tot *= i;
            while (j <= m&&tot%j == 0) tot = tot / j++;
        }
        int k = gcd(tot, f[n][m][3] + f[n][m][2]);
        printf("%d/%d\n", (f[n][m][2] + f[n][m][3]) / k, tot / k);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值