题目链接
题意
一个 (n+2)×m 的矩形由 1×1 的小矩形构成。
每天第 2−(n+1) 行最左和最右的矩形都有 ba 的概率消失。
问 t 天后大矩形四联通的概率。
对 109+7 取模。
思路
令 p=ba。
考虑 DP 求解。
预处理出 t 天后每行左 / 右恰好 i 个矩形消失的概率,设为 ci。
易得:ci=Cti⋅pi⋅(1−p)t−i。
设 fi,l,r 为第 i 行只剩矩形 l−r 时前 i 行仍联通的概率。
lfi,r 为第 i 行最右边的矩形为 r 时前 i 行仍联通的概率,rfi,l 同理。
lsi,r 为第 i 行最右边的矩形为 1−r 时前 i 行仍联通的概率,rsi,l 同理。
sumi 为前 i 行联通的总概率(其实就是 lsi,m)。
转移方程如下:
fi,l,rlfi,rlsi,r=(sumi−1−lsi−1,l−1−rsi−1,r+1)⋅cl−1⋅cm−r=l=1∑rfi,l,r, rfi,r=r=l∑mfi,l,r=j=1∑rlfi,j, rsi,l=j=l∑mrfi,j
然而这种做法时间复杂度是 O(nm2) 的,不能通过。
其实 ls,rs 本质上是相同的,即 lsi,j=rsi,m−j+1。
所以 fi,l,r=(lsi−1,m+lsi−1,l−1+lsi−1,m−r)⋅cl−1⋅cm−r。
继续推导:
lfi,r=l=1∑r(lsi−1,m+lsi−1,l−1+lsi−1,m−r)⋅cl−1⋅cm−r=(l=1∑r((lsi−1,m−lsi−1,l−1)⋅cl−1)−lsi−1,m−r⋅l=1∑rcl−1)⋅cm−r
维护前缀和,可在 O(1) 时间复杂度内求出 lfi,r。
答案为 lsn,m。
实现
代码中变量名与公式中有偏差。
sc[i]
为 ∑j=0icj。
f[i][j]
为 lfi,j。
s[i][j]
为 lsi,j。
ss[i][j]
为 ∑k=1j((lsi−1,m−lsi−1,k−1)⋅ck−1)。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<cstdio> using namespace std; const int N=1500,K=1e5,mod=1e9+7; int n,m,a,b,k,p; long long fac[K+1],inv[K+1],c[N+1],sc[N+1],f[N+1][N+1],s[N+1][N+1],ss[N+1]; long long pow(long long x,int times) { long long res=1; for(;times;x=x*x%mod,times>>=1) { if(times&1) { res=res*x%mod; } } return res; } void init() { fac[0]=1; for(int i=1;i<=k;++i) { fac[i]=fac[i-1]*i%mod; } inv[k]=pow(fac[k],mod-2); for(int i=k;i;--i) { inv[i-1]=inv[i]*i%mod; } return; } inline long long C(int n,int m) { return fac[n]*inv[m]%mod*inv[n-m]%mod; } int main() { scanf("%d%d%d%d%d",&n,&m,&a,&b,&k); p=a*pow(b,mod-2)%mod; init(); for(int i=0;(i<=m)&&(i<=k);++i) { c[i]=C(k,i)*pow(p,i)%mod*pow(1-p,k-i)%mod; } sc[0]=c[0]; f[0][m]=s[0][m]=1; for(int i=1;i<m;++i) { sc[i]=(sc[i-1]+c[i])%mod; } for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { ss[j]=(ss[j-1]+(s[i-1][m]-s[i-1][j-1])*c[j-1])%mod; f[i][j]=(ss[j]-s[i-1][m-j]*sc[j-1])%mod*c[m-j]%mod; s[i][j]=(s[i][j-1]+f[i][j])%mod; } } printf("%lld\n",(s[n][m]+mod)%mod); return 0; }
|