[题解]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"); }