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

概率dp入门题,转移方程为dp[i]=dp[i-1]*p+dp[i-2]*(1-p)

因为n个数字上限很大,所以常规的概率dp基本不可能,要用矩阵优化。

把路程分成n+1段,分别计算通过每段的成功率,即刚好跨越地雷的概率(dp[地雷x+1])

算好每段之后把每段的成功率相乘。

(若有两颗地雷相邻那么成功率是0)

#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 20

using namespace std;

struct node
{
    int n;
    double rect[N][N];
    struct node operator* (const node b)
    {
        node tem;
        tem.n=n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                tem.rect[i][j]=0;
                for(int k=1;k<=n;k++)
                        tem.rect[i][j]+=rect[i][k]*b.rect[k][j];
            }
        return tem;
    };
};

node pin(node a,LL b)//aµÄb´ÎÃÝ
{
    node ans;
    ans.n=a.n;
    for(int i=1;i<=a.n;i++)
        for(int j=1;j<=a.n;j++)
        {
            if(i==j)
                ans.rect[i][j]=1;
            else
                ans.rect[i][j]=0;
        }
    while(b)
    {
        if(b&1)
            ans=a*ans;
        b>>=1;
        a=a*a;
    }
    return ans;
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        double p;
        scanf("%lf",&p);
        LL a[20];
        double b[20];
        double sum=1;
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
            sort(a+1,a+1+n);
        a[0]=0;
        node tem;
        tem.n=2;
        tem.rect[1][1]=p;
        tem.rect[1][2]=1;
        tem.rect[2][1]=1-p;
        tem.rect[2][2]=0;
        //printf("%lf\n",pin(tem,4).rect[1][1]);
        for(int i=n;i>=1;i--)
        {
            a[i]-=(a[i-1]+2);

            if(a[i]<0)
            {
                b[i]=0;
                continue;
            }
            node ans=pin(tem,a[i]);
            b[i]=ans.rect[1][1]*(1-p);

            //cout << "b" << i << "= " << b[i] << endl;
        }
        for(int i=1;i<=n;i++)
        {
            sum*=b[i];
        }
        printf("%.7f\n",sum);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/brotherHaiNo1/p/8413883.html

时间: 2024-07-31 15:58:04

(POJ 3744)Scout YYF I(概率dp+矩阵快速幂)的相关文章

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

题意:小明要从1走过一段直线雷区,给定n个地雷的坐标,他走一步的概率是p,两步的概率为1-p,问你他能安全通过雷区的概率. 析:很明显这是一个概率DP,用d(i)表示到达 i 时他安全的概率,那么d[i] = p * d[i-1] + (1-p) * d[i-2];这个状态转移方程很好理解, 就是说要想到达 i 要么从第 i-1 走一步,要么从 i-2 走两步,最后加起来,然后问题来了,这个数可能达到 1E8,那么时间空间复杂度都受不了, 观察这个状态转移方程,是不是很像Fibnacci数列,所

[poj3744]Scout YYF I(概率dp+矩阵快速幂)

题意:在一维空间上存在一些雷,求安全通过的概率.其中人有$p$的概率前进一步,$1-p$的概率前进两步. 解题关键:若不考虑雷,则有转移方程:$dp[i] = p*dp[i - 1] + (1 - p)*dp[i - 2]$ 由于雷的数量很少,所以可以以雷为界,将区域分开,在每个区域中,通过该段的概率等于1-踩到该段终点的地雷的概率.然后用矩阵快速幂优化一下即可 1 #include<cstdio> 2 #include<cstring> 3 #include<algorit

poj 3744 Scout YYF I 概率dp+矩阵乘法

分析: dis(k,v1,v2)函数求到当前位置概率为v1,到当前位置之前一步的概率为v2,前进k步到达位置的概率,然后矩阵加速. 代码: //poj 3744 //sep9 #include <iostream> #include <algorithm> using namespace std; int pos[12]; double p,mat[4][4]; double ans[4][4]; void mul1() { double c[4][4]; c[0][1]=c[1]

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

Scout YYF I 题目连接: http://poj.org/problem?id=3744 题意: 有个人要到一个叫“mine road”的地方,路线是一条直线,起点在1,路上有N个地雷,坐标在[1, 100000000]之间,这人每次有p(0.25≤p≤0.75)的概率向前走一步,且有1-p的概率向前走两步,问这货安全通过雷区到达"mine road"的概率 题解: 利用特征方程求出通项表达式,要走过有雷的地方f(n+1)=f(n-1)*(1-p).   PS:也可以用矩阵快速

poj 3744 Scout YYF I(概率dp,矩阵优化)

Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5020   Accepted: 1355 Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. After overcoming a series difficulties,

poj 3744 Scout YYF I (概率DP+矩阵快速幂)

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5062   Accepted: 1370 Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. After overcoming a series difficulties, YYF is now

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] ````````` 然后求出安全通过每一段的概率  

POJ3744——概率DP 矩阵快速幂优化——Scout YYF I

http://poj.org/problem?id=3744 矩阵快速幂: 利用DP的递推式 就本题来说 dp[i] = p*dp[i-1] + (1-p)*dp[i-2] 由于x非常大最大1亿,这样的话复杂度就为1亿 所以这里可以用矩阵的思想 [dp[i]   dp[i-1] ] = [ dp[i-1]  dp[i-2] ] | p   1 - p| | 1      0  | 递推得到 n - 1 [dp[n]   dp[n-1]] = [dp[1]   dp[2] ] |p   1 - p

poj 3744 概率dp 矩阵快速幂优化

一位童子兵要穿过一条路,路上有些地方放着地雷.这位童子兵非常好玩,走路一蹦一跳的.每次他在 i 位置有 p 的概率走一步到 i+1 ,或者 (1-p) 的概率跳一步到 i+2.童子兵初始在1位置,求他安全通过这条道路的概率. 以所在位置为状态,dp[i] 表示在位置 i 的安全的概率. dp[i] = p * dp[i-1] + (1 - p) * dp[i-2]; // i 位置没有地雷 但是题目数据的范围是 10^8 这样dp的话会 TLE. 想想可以用矩阵快速幂优化.简单退出矩阵是 |p

POJ 3420 Quad Tiling 状压DP+矩阵快速幂

链接:http://poj.org/problem?id=3420 题意:给一个4*N(1 ≤ N ≤ 1e9)的矩形空间,并且给不限块数的1*2的多米诺骨牌,问是由多少种方式能把这个矩形空间填满. 思路:看到这种问题果断想到状压,虽然是在看矩阵的时候看到的这道题.dp[i][j]表示在第i行状态为j的情况下的填满方式数,j的二进制表示中0表示对应位置上一行的骨牌是竖放,或者对应位置的骨牌是横放,1则表示该行该位置的骨牌是竖放.由于N最大1e9所以O(n)的DP绝对超时,用矩阵快速幂来加速DP递