Scout YYF I POJ - 3744(概率dp + 矩阵快速幂)

Posted wtsruvf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scout YYF I POJ - 3744(概率dp + 矩阵快速幂)相关的知识,希望对你有一定的参考价值。

题意:

  一条路上有n个地雷,你从1开始走,单位时间内有p的概率走一步,1-p的概率走两步,问安全通过这条路的概率

解析:

  很容易想到 dp[i] = p * dp[i-1] + (1 - p) * dp[i];

  然而。。。t,但这个式子明显可以用矩阵快速幂加个氮气一下加速一下。。。

  把所有的点输入之后 sort一下,那么就能把这条路分成很多段 每一段以地雷为分界线

 1 - x[0]  x[0]+1 - x[1]  x[1]+1 - x[2] `````````

然后求出安全通过每一段的概率   乘一下就好了

技术分享图片

呐 公式是这个  让 a = p   b = (1 - p) 就好啦

代码是我改了一下bin神的  为什么要改。。。我没大懂大佬们写的多一次方啥意思。。。然后  就讨论了一下范围计算

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;

struct Matrix
{
    double mat[2][2];
};
Matrix mul(Matrix a,Matrix b)
{
    Matrix ret;
    for(int i=0;i<2;i++)
      for(int j=0;j<2;j++)
      {
          ret.mat[i][j]=0;
          for(int k=0;k<2;k++)
            ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
      }
    return ret;
}
Matrix pow_M(Matrix a,int n)
{
    Matrix ret;
    memset(ret.mat,0,sizeof(ret.mat));
    for(int i=0;i<2;i++)ret.mat[i][i]=1;
    Matrix temp=a;
    while(n)
    {
        if(n&1)ret=mul(ret,temp);
        temp=mul(temp,temp);
        n>>=1;
    }
    return ret;
}

int x[30];
int main()
{
    int n;
    double p;
    while(cin >> n >> p)
    {
        for(int i=0;i<n;i++)
          scanf("%d",&x[i]);
        sort(x,x+n);
        if(x[0] == 1)
        {
            puts("0.0000000");
            continue;
        }
        double ans=1;
        Matrix tt;
        tt.mat[0][0]=p;
        tt.mat[0][1]=1-p;
        tt.mat[1][0]=1;
        tt.mat[1][1]=0;
        Matrix temp;
        if(x[0] > 2)
        {
            temp=pow_M(tt,x[0]-2);
            ans*=(1-(temp.mat[0][0] * p + temp.mat[0][1]));
        }
        else if(x[0] == 2)
            ans *= (1 - p);
        for(int i=1;i<n;i++)
        {
            if(x[i]==x[i-1])continue;
            if(x[i]-x[i-1] > 2)
            {
                temp=pow_M(tt,x[i]-x[i-1]-2);
                ans *= (1-(temp.mat[0][0] * p + temp.mat[0][1]));
            }
            else if(x[i]-x[i-1] == 2)
                ans *= (1 - p);
            else if(x[i] - x[i-1] == 1)
                ans = 0;
        }
        printf("%.7f
", ans);
    }
    return 0;
}

以上是关于Scout YYF I POJ - 3744(概率dp + 矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章

POJ3744 Scout YYF I (矩阵优化的概率DP)

[poj 3744]Scout YYF I

poj3744 Scout YYF I

POJ 3744:Scout YYF I 概率DP+特征方程+快速幂

poj 3744 Scout (Another) YYF I - 概率与期望 - 动态规划 - 矩阵快速幂

POJ3744Scout YYF I