bzoj3150: [Ctsc2013]猴子
算是一道概率dp吧。
状态互相依赖的动态规划,需要使用高斯消元。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<cstdlib> #include<ctime> #include<algorithm> using namespace std; #define mid ((l+r)>>1) #define LL long long #define FILE "dealing" #define up(i,j,n) for(LL i=(j);i<=(n);i++) #define pii pair<int,int> int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return f*x; } const int maxn=110,inf=100000000,mod=998244353; const double eps=0.000000001; int n,m; double p[maxn][maxn],M[maxn][maxn],t[maxn]; char s[maxn]; bool cmp(double x,double y){return abs(x-y)<=eps;} int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read(); up(i,1,n)up(j,1,n)scanf("%lf",&p[i][j]); up(i,1,n-1){ M[i][i]=1-n; up(j,1,n)if(i!=j)M[i][j]=p[i][j],M[i][i]+=p[i][j]; } up(i,1,n+1)M[n][i]=1; up(i,1,n){ int k=i; up(j,i,n) if(fabs(M[j][i])>fabs(M[k][i])) k=j; if(i!=k){ for(int h=1;h<=n+1;h++)t[h]=M[i][h]; for(int h=1;h<=n+1;h++)M[i][h]=M[k][h]; for(int h=1;h<=n+1;h++)M[k][h]=t[h]; } up(j,i+1,n+1){ double k=M[j][i]/M[i][i]; for(int h=n+1;h>=1;h--)M[j][h]-=M[i][h]*k; } } for(int i=n;i>=1;i--){ up(j,i+1,n)M[i][n+1]-=M[i][j]*M[j][n+1]; M[i][n+1]/=M[i][i]; } while(m--){ scanf("%s",s+1); double ans=0; up(i,1,n)if(s[i]=='1')ans+=M[i][n+1]; printf("%.8lf\n",ans); } return 0; }