BZOJ 3150 [Ctsc2013]猴子 ——期望DP 高斯消元

一堆牌的期望等于每张牌的期望值和。

考虑三个人的游戏即可得到。

然后每张牌遇到另外一张的概率相同,然后就可以列方程求解了。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m;
#define maxn 105
#define F(i,j,k) for (int i=j;i<=k;++i)
double p[maxn][maxn],a[maxn][maxn];
char s[maxn];
void Gauss()
{
    F(i,1,n)
    {
        int tmp=i; F(j,i+1,n) if (fabs(a[j][i])>fabs(a[tmp][i])) tmp=j;
        F(j,1,n+1) swap(a[tmp][j],a[i][j]);
        F(j,1,n) if (j!=i)
        {
            double t=a[j][i]/a[i][i];
            F(k,i,n+1) a[j][k]-=t*a[i][k];
        }
    }
    F(i,1,n) a[i][n+1]/=a[i][i];
}
int main()
{
    scanf("%d%d",&n,&m);//printf("n is %d m is %d\n",n,m);
    F(i,1,n) F(j,1,n) scanf("%lf",&p[i][j]);
    F(i,1,n-1)
    {
        a[i][i]=1-n;
        F(j,1,n) if (i!=j) a[i][j]+=p[i][j],a[i][i]+=p[i][j];
    }
    F(i,1,n) a[n][i]=1; a[n][n+1]=1;
    Gauss();
    double ans;
    F(i,1,m)
    {
        scanf("%s",s+1);ans=0;
        F(j,1,n) if (s[j]=='1') ans+=a[j][n+1];
        printf("%.8lf\n",ans);
    }
}

  

posted @ 2017-05-05 16:22  SfailSth  阅读(343)  评论(0编辑  收藏  举报