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 at the start of enemy‘s famous "mine road". This is a very long road, on which there are numbers of mines.
At first, YYF is at step one. For each step after that, YYF will walk one step with a probability of p, or jump two step with a probality of 1-p. Here is the task, given the place of each mine, please calculate the probality that YYF can
go through the "mine road" safely.

Input

The input contains many test cases ended with EOF.

Each test case contains two lines.

The First line of each test case is N (1 ≤ N ≤ 10) and p (0.25 ≤ p ≤ 0.75) seperated by a single blank, standing for the number of mines and the probability to walk one step.

The Second line of each test case is N integer standing for the place of N mines. Each integer is in the range of [1, 100000000].

Output

For each test case, output the probabilty in a single line with the precision to 7 digits after the decimal point.

Sample Input

1 0.5
2
2 0.5
2 4

Sample Output

0.5000000
0.2500000

题意:人人从1开始走,p的概率走1步,1-p的概率走2步,求不踩雷的概率。地雷数N<=10,坐标范围在100000000内。

思路:人走到第i位置的概率为dp[i]=dp[i-1]*p+dp[i-2]*(1-p),由于数据范围较大,可有矩阵快速幂快速求出答案;

构造矩阵     | P ,  1 |   即   | dp[n+1] , dp[n] |  =

| dp[n] , dp[n-1] |    *  | P ,  1 |

| 1-P , 0 |                                                          |
1-P , 0 |

然后将每个a[i]+1到a[i+1]看做一段单独处理就行。

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn=100000050;

struct node
{
    double mat[2][2];
}A,B,C;

double dp[maxn],p;
int n,a[15];

void input()
{
    for(int i=0;i<n;i++)  scanf("%d",&a[i]);
    sort(a,a+n);
    A.mat[0][0]=p,A.mat[0][1]=1.0;
    A.mat[1][0]=1.0-p,A.mat[1][1]=0.0;
}

node mul(node p,node q)   //  矩阵相乘
{
      node ans;
      for(int i=0;i<2;i++)
           for(int j=0;j<2;j++)
           {
                ans.mat[i][j]=0.0;
                for(int k=0;k<2;k++)
                    ans.mat[i][j]+=p.mat[i][k]*q.mat[k][j];
           }
      return ans;
}

node pow(node w,int num)   //  快速幂
{
    node ret=B,c=w;
    int coun=num;
    while(coun)
    {
        if(coun & 1)  ret=mul(ret,c);
        coun>>=1;
        c=mul(c,c);
    }
    return ret;
}

void solve()
{
    int now=1;
    double f1=0.0,f2=1.0;
    for(int i=0;i<n;i++)
    {
         if(a[i]-now>=1)
         {
              node tmp=pow(A,a[i]-1-now);
              f2=(f2*tmp.mat[0][0]+f1*tmp.mat[1][0])*(1.0-p);
              f1=0.0;
              now=a[i]+1;
         }
         else
         {
             printf("0.0000000\n");
             return ;
         }
    }
    printf("%.7f\n",f2);
}

int main()
{
    B.mat[0][0]=1.0,B.mat[0][1]=0.0;
    B.mat[1][0]=0.0,B.mat[1][1]=1.0;
    while(scanf("%d %lf",&n,&p)!=EOF)
    {
         input();
         solve();
    }
    return 0;
}
时间: 2024-10-12 12:06:12

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,

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递