[题解]BZOJ_1867_钉子和小球(简单dp)

关于如何处理分数形式一个普适的做法是开个结构体记录分子分母,重载运算符做加减法,

但是在数据范围小的情况下可以假设开始时有$2^n$个小球下落,这样可以避免处理分数

#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn=53;
int n,m,cnt,a[maxn][maxn];
ll f[maxn][maxn];
char b[maxn][maxn];
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=i;j++){
        while(b[i][j]!='*' && b[i][j]!='.')scanf("%c",&b[i][j]);
        a[i][j]=(b[i][j]=='*');
    }
    f[1][1]=1ll<<n;
    int x,y;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=i;j++){
        if(a[i][j]){
            f[i+1][j]+=f[i][j]/2;
            f[i+1][j+1]+=f[i][j]/2;
        }
        else f[i+2][j+1]+=f[i][j];
    }
    ll s=1ll<<n;
    ll k=gcd(f[n+1][m+1],s);
    if(f[n+1][m+1])printf("%lld/%lld",f[n+1][m+1]/k,s/k);
    else printf("0/1");
}

 

posted @ 2019-07-18 13:48  羊肉汤泡煎饼  阅读(164)  评论(0编辑  收藏  举报