Description
Input
Output
Sample Input
5 2 * * . * * * * . * * * * * * *
Sample Output
7/16
为了避免小数的计算,我们假设最上面有2^n次方个球,然后求出最后到底层有几个球,再以这个数字和2^n求GCD得到概率
#include <iostream> #include <stdio.h> #include <string.h> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <math.h> #include <algorithm> using namespace std; #define ls 2*i #define rs 2*i+1 #define up(i,x,y) for(i=x;i<=y;i++) #define down(i,x,y) for(i=x;i>=y;i--) #define mem(a,x) memset(a,x,sizeof(a)) #define w(a) while(a) #define LL long long const double pi = acos(-1.0); #define Len 63 #define mod 19999997 const int INF = 0x3f3f3f3f; LL dp[55][55],a[100005],len; char str[10000]; LL GCD(LL a,LL b) { if(b==0) return a; return GCD(b,a%b); } int main() { LL i,j,k,n,m; w(~scanf("%I64d%I64d",&n,&m)) { len = 1; up(i,1,n) { up(j,1,i) { scanf("%s",str); if(str[0]=='*') a[len++] = 1; else a[len++] = 0; } } mem(dp,0); dp[1][1] = 1LL<<n; up(i,1,n) { LL t = (i-1)*i/2;//这一排最右边 up(j,1,i)//枚举这一盘所有位置 { if(a[j+t])//钉子存在,那么往左往右各走一般 { dp[i+1][j] += dp[i][j]/2; dp[i+1][j+1] += dp[i][j]/2; } else//钉子不在,往下走,因为是三角形的形状,所以j要+1 dp[i+2][j+1] += dp[i][j]; } } LL x = 1LL<<n; LL r = GCD(x,dp[n+1][m+1]); printf("%I64d/%I64d\n",dp[n+1][m+1]/r,x/r); } return 0; }
原文地址:http://blog.csdn.net/libin56842/article/details/45065761