管道维修

管道维修

n*m个格子,每个格子有\(p_{ij}\)的概率堵上。如果一个格子堵上了,那么清理它需要一步。只有当一个格子与外部相联通且被疏通时,你可以去清理它周围的格子。问每一个格子被清理完的期望步数。

颠覆了我对期望题的认知……原来此题非期望dp,而是直接从期望的定义出发。\(n^3\)预处理即可。

#include <cstdio>
#include <algorithm>
using namespace std;
 
typedef long long LL;
const int maxn=205, mod=1e9+7;
int n, m;
LL p[maxn][maxn], E[maxn][maxn];
int f[maxn][maxn][maxn];
 
int fpow(int a, int x){
    LL base=a, ans=1;
    for (; x; x>>=1, (base*=base)%=mod)
        if (x&1) (ans*=base)%=mod;
    return ans;
}
int inv(int x){ return fpow(x, mod-2); }
int P(int x, int y){ return x<0||y<0?0:p[x][y]; }
 
int main(){
    scanf("%d%d", &n, &m); int a, b;
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j){
            scanf("%d%d", &a, &b);
            p[i][j]=f[i][j][0]=E[i][j]=1ll*a*inv(b)%mod; }
    for (int k=1; k<=max(n, m)/2; ++k)
        for (int i=1; i<=n; ++i)
            for (int j=1; j<=m; ++j)
                f[i][j][k]=1ll*f[i-1][j][k-1]*f[i+1][j][k-1]%mod
                        *P(i, j-k)%mod*P(i, j-k+1)%mod*P(i, j+k)%mod*P(i, j+k-1)%mod*inv(k>2?f[i][j][k-2]:p[i][j])%mod,
                E[i][j]+=f[i][j][k], E[i][j]%=mod;
    for (int i=1; i<=n; ++i){
        for (int j=1; j<=m; ++j)
            printf("%lld ", E[i][j]);
        puts(""); }
    return 0;
}
posted @ 2018-09-25 15:59 pechpo 阅读(...) 评论(...) 编辑 收藏