POJ 3744 Scout YYF I(概率Dp)

来源:互联网 发布:java web完整项目 编辑:程序博客网 时间:2024/06/10 02:11

题意:给出走一步的概率,和走两步的概率,询问顺利通过所有格子,图中不踩到坏格子上的概率


思路:DP[i]=(1-p) DP[i-2] + p*Dp[i-1] 很好推,但是范围大了不能暴力推, 拿矩阵分开逐步优化下。

DP【i】表示顺利通过i格子的概率。 对于每一个雷区,把它和左侧看为整体

#include <iostream>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <queue>#include <algorithm>using namespace std;typedef long long ll;const int maxn=3;struct Matrix//矩阵的类{  double a[maxn][maxn];  void init()           //将其初始化为单位矩阵  {    memset(a,0,sizeof(a));    for(int i=1;i<maxn;i++)      a[i][i]=1;  }}  ;int c[1000005];Matrix mul(Matrix a,Matrix b)  //(a*b)%mod  矩阵乘法{  Matrix ans;  memset(ans.a,0,sizeof(ans.a));  for(int i=1;i<maxn;i++)  {        ans.a[i][i]=1;  }  for(int i=1;i<maxn;i++)    for(int j=1;j<maxn;j++)    {      ans.a[i][j]=0;      for(int k=1;k<maxn;k++)        ans.a[i][j]+=a.a[i][k]*b.a[k][j] ;    }    return ans;}Matrix pow(Matrix a,int m){    Matrix res ;    memset(res.a,0,sizeof(res.a));    for(int i=1;i<maxn;i++)    {        res.a[i][i]=1;    }    while(m)    {        if(m&1)        {            res=mul(a,res);        }        a=mul(a,a);        m/=2;    }    return res;}int main(){    double p;    int t=0;    int n;    while(~scanf("%d%lf",&n,&p) )    {        for(int i=1;i<=n;i++)            scanf("%d",&c[i]);        sort(c+1,c+1+n);        Matrix base,res;        base.a[1][1]=p,base.a[1][2]=1-p;        base.a[2][1]=1,base.a[2][2]=0;        double ans=1;        res=pow( base,c[1]-1 );        ans=ans*(1-res.a[1][1]);        for(int i=2;i<=n;i++)        {            if(c[i]==c[i-1]) {                continue;            }            res=pow(base,c[i]-c[i-1]-1);            ans=ans*(1-res.a[1][1]);        }        printf("%.7lf\n",ans);    }}