本题动态规划问题的状态转移很明显在小球下落的每一层里面发生变化,所以使用二维dp[i][j]来表示某一行某一个钉子或者去掉的钉子所拥有的小球。
题目要求最后以分数的方式给出答案,那么我们可以以小球的数量比下手,小球每进过一次钉子就会分裂成两个,这样就去考虑他到达底部某个槽子里面有多少个小球,然后除于到达底部的全部小球就是最后要的结果。
那么对于去掉钉子的地方呢,去掉钉子的地方会直接性的下落两层,那么就业是说直接给下落两层的地方的数量变成该地方乘四即可。
#include <bits/stdc++.h>


using namespace std;
#define int long long
const int maxn = 55;
int dp[55][55*2];
char a[maxn][maxn];

void calc(int a, int b) {
    int c = gcd(a, b);
    a = a/c;
    b = b/c;
    cout<<a<<"/"<<b;
} 

signed main() {
    int n, m;
    cin>>n>>m;
    for (int i=0;i<n;i++) {
        for (int j=0;j<=i;j++) {
            cin>>a[i][j];
        }
    }
    dp[0][0] = 1;
    for (int i=0;i<n;i++) {
        for (int j=0;j<=i;j++) {
            if (a[i][j]=='*') {
                dp[i+1][j] += dp[i][j];
                dp[i+1][j+1] += dp[i][j];
            }
            if (a[i][j]=='.') {
                dp[i+2][j+1] += dp[i][j]*4;
            }
        }
    }
    int sum = 0;
    for (int j=0;j<n+1;j++) {
        sum += dp[n][j];
    }
    calc(dp[n][m], sum);
    return 0;
}