当前位置: 代码迷 >> 综合 >> bzoj1867: [Noi1999]钉子和小球
  详细解决方案

bzoj1867: [Noi1999]钉子和小球

热度:83   发布时间:2023-10-29 11:13:26.0

题意

点我

题解

这应该是最水的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;
}