bzoj1867: [Noi1999]钉子和小球

来源:互联网 发布:国内咨询公司 知乎 编辑:程序博客网 时间:2024/05/21 09:11

题意

点我

题解

这应该是最水的NOI了吧
你就DP一下就好了
然后在记得要约分,就不用开高精度了

#include<cstdio>#include<cstring>const int N=55;typedef long long LL;LL n,m,nn;bool tf[N*N];//这个钉子还在不在bool ooo[N][N];//第i行的第j个属于什么状态 //true:在   false:不在 LL f[N][N];//分子LL g[N][N];//分母 LL gcd (LL x,LL y){    return y==0?x:gcd(y,x%y);}void Add (LL x,LL y,LL a,LL b){    LL X=gcd(g[x][y],b);//  printf("YES:%lld %lld %lld %lld %lld\n",x,y,a,b,X);    LL L=g[x][y]/X*b;    f[x][y]=f[x][y]*(b/X)+a*(g[x][y]/X);    g[x][y]=L;    X=gcd(f[x][y],g[x][y]);    if (X==0) return ;    g[x][y]/=X;f[x][y]/=X;}int main(){    scanf("%lld%lld",&n,&m);nn=n*(1+n)/2;m++;    LL cnt=0;//现在已经     while (cnt<nn)    {        char ch=getchar();        if (ch=='*') tf[++cnt]=true;        if (ch=='.') tf[++cnt]=false;    }    LL num=0;    for (LL u=1;u<=n;u++)        for (LL i=1;i<=u;i++)        {            ooo[u][i]=tf[++num];            g[u][i]=1;            f[u][i]=0;        }    for (LL u=1;u<=m;u++) g[n+1][u]=1,f[n+1][u]=0;    f[1][1]=1;g[1][1]=1;    for (LL u=1;u<=n;u++)        for (LL i=1;i<=u;i++)//到第几个        {        //  printf("%lld %lld %lld %lld\n",u,i,f[u][i],g[u][i]);            LL a=f[u][i],b=g[u][i];            if (ooo[u][i]==true)//钉子还在            {                if (a%2==0) a/=2;                else b*=2;                Add(u+1,i,a,b);                Add(u+1,i+1,a,b);            }            else            {                Add(u+2,i+1,a,b);            }        }    printf("%lld/%lld",f[n+1][m],g[n+1][m]);/*  for (LL u=1;u<=n+1;u++)        printf("YES:%lld %lld\n",f[n+1][u],g[n+1][u]);*/    return 0;}
原创粉丝点击