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
",ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/chadinblog/p/6340225.html