hdu 5194 DZY Loves Balls (dp)

题意:

给出n个黑球m个红球,随机抽取球,然后根据抽取的球得到一个序列,黑球表示1,红球表示0.问这样的序列01现的次数和出现01串的串的个数比是剁手。

题解:

这道题,开始用状态位枚举,华丽的挂了。dfs可过。dp速度快!dp[i][j][k][l]表示取了i个黑球j个红球01出现次数为k,以l为结尾对应串的个数。

最后01在所有串出现的次数通过枚举k计算。出现01串的串的个数是C[n+m][n];

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef long long ll;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
const int oo=0x3f3f3f3f;
const int MOD=1000000007;
const int maxn=15;
ll dp[maxn][maxn][maxn][2];
ll C[maxn<<1][maxn<<1];

int gcd(int a,int b){
    return b==0 ? a : gcd(b,a%b);
}

int main(){
    //freopen("E:\\read.txt","r",stdin);
    for(int i=0;i<=24;i++){
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;j++)
            C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    memset(dp,0,sizeof dp);
    dp[1][0][0][1]=1;
    dp[0][1][0][0]=1;
    for(int i=0;i<=12;i++){
        for(int j=0;j<=12;j++){
            for(int k=0;k<=12;k++){
               dp[i+1][j][k+1][1]+=dp[i][j][k][0];
               dp[i][j+1][k][0]+=dp[i][j][k][0];

               dp[i+1][j][k][1]+=dp[i][j][k][1];
               dp[i][j+1][k][0]+=dp[i][j][k][1];
            }
        }
    }
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF){
        ll u=0,d=C[n+m][n];
        for(int i=1;i<=12;i++)u+=i*(dp[n][m][i][0]+dp[n][m][i][1]);
        ll t=gcd(u,d);
        u/=t;
        d/=t;
        printf("%I64d/%I64d\n",u,d);
    }
	return 0;
}







你可能感兴趣的:(hdu 5194 DZY Loves Balls (dp))