题解:P5750 [NOI1999] 钉子和小球

题面

思路

明显的概率DP,设 \(f_{i,j}\) 为小球落到位置 \((i,j)\) 的概率,容易得到状态转移的方法。

\(a_{i-1,j-1}\) 有钉子时,\(f_{i,j}=f_{i,j}+\frac{f_{i-1,j-1}}{2} \times 50\%\)
\(a_{i-1,j}\) 有钉子时,\(f_{i,j}=f_{i,j}+f_{i-1,j} \times 50 \%\)
\(a_{i-2,j-1}\) 没有钉子时,\(f_{i,j}=f_{i,j}+f_{i-2,j-1}\)

由于本题需要输出分数,所以我们可以用一个结构体储存答案。

于是这题就做完了。

代码

#include<bits/stdc++.h>
using namespace std;
#define int __int128
const int N=60,mod=1e9+7;
int n,m;
char a[N][N];
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9')
		x=x*10+ch-'0',ch=getchar();
	return x*f;
}
void write(int x){
	if(x<0)
		putchar('-'),x=-x;
	if(x>9)
		write(x/10);
	putchar(x%10+'0');
	return;
}
int gcd(int a,int b){ return b?gcd(b,a%b):a; }
int lcm(int a,int b){ return a*b/gcd(a,b); }
struct node{
	int fz,fm;
	node operator +(const node x) const{
		if(fm==0) return x;
		if(x.fm==0) return *this;
		node res=(node){fz,fm};
		int u=lcm(res.fm,x.fm);
		res.fz=(u/fm)*fz+(u/x.fm)*x.fz;
		res.fm=u;
		int g=gcd(res.fz,res.fm);
		if(!g) return res;
		res.fz/=g;
		res.fm/=g;
		return res;
	}
	node operator *(const node x) const{
		node res=(node){fz,fm},resx=(node){x.fz,x.fm};
		int g1=gcd(res.fz,resx.fm),g2=gcd(res.fm,resx.fz);
		res.fz/=g1;resx.fm/=g1;
		res.fm/=g2;resx.fz/=g2;
		res.fz*=x.fz;
		res.fm*=x.fm;
		if(!res.fz || !res.fm) return (node){0,1};
		int g=gcd(res.fz,res.fm);
		if(!g) return res;
		res.fz/=g;
		res.fm/=g;
		return res;
	}
	void output(){
		if(fz==0){
			cout<<"0/1";
			return;
		}
		int g=gcd(fz,fm);
		fz/=g;
		fm/=g;
		write(fz);
		cout<<'/';
		write(fm);
	}
}f[N][N];
signed main(){
	n=read();m=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++){
			cin>>a[i][j];
		}
		a[i][0]='.';
	}
	f[1][1].fz=f[1][1].fm=1;
	for(int i=2;i<=n+1;i++){
		for(int j=1;j<=i;j++){
			f[i][j]=(node){0,1};
			if(i>2 && j>1 && a[i-2][j-1]=='.'){
				f[i][j]=f[i][j]+f[i-2][j-1];
			}
			if(a[i-1][j-1]=='*') f[i][j]=f[i][j]+f[i-1][j-1]*(node){1,2};
			if(a[i-1][j]=='*') f[i][j]=f[i][j]+f[i-1][j]*(node){1,2};
		}
	}
	f[n+1][m+1].output();
	return 0;
}
posted @ 2025-08-30 17:43  幻琳  阅读(8)  评论(0)    收藏  举报