zoukankan      html  css  js  c++  java
  • POJ3744 Scout YYF I (矩阵优化的概率DP)

    Scout YYF I
    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

    一位童子兵要穿过一条路,路上有些地方放着地雷。这位童子兵非常好玩,走路一蹦一跳的。
    每次他在 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 1-p| * |dp[i]   | = |dp[i+1]|
    |1 0    |   |dp[i-1]|    |dp[i]     |
    而这时地雷位置是不满足这个矩阵的,因此我们得对地雷位置进行特判。而两个地雷中间的位置可以用快速幂优化。
    假设 k 位置放有地雷,,我们可以得到 dp[k+1] = dp[k-1] * (1 - p);
    对于炸弹位置为 a[i] 和 a[i+1] 之间的数,知道 dp[a[i]+1] 后可以推出
    (视0位置有颗地雷,有地雷的位置的dp值为0)
    于是我们可以对两个前后两个地雷之间用快速幂优化,并最终得到答案dp[max(a[i])+1];
    转自:http://blog.csdn.net/xuelanghu407/article/details/47172759

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cmath>
     6 using namespace std;
     7 
     8 int n;double p;
     9 int x[30];
    10 
    11 struct Node{double mat[2][2];};
    12 Node mul(Node a,Node b)
    13 {
    14     Node res;
    15     for(int i=0;i<2;i++)
    16       for(int j=0;j<2;j++)
    17       {
    18           res.mat[i][j]=0;
    19           for(int k=0;k<2;k++) res.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
    20       }
    21     return res;
    22 }
    23 Node pow_M(Node a,int n)
    24 {
    25     Node res;
    26     memset(res.mat,0,sizeof(res.mat));
    27     for(int i=0;i<2;i++)
    28         res.mat[i][i]=1;
    29     Node temp=a;
    30     while(n)
    31     {
    32         if(n&1)res=mul(res,temp);
    33         temp=mul(temp,temp);
    34         n>>=1;
    35     }
    36     return res;
    37 }
    38 int main()
    39 {
    40     while(~scanf("%d%lf",&n,&p))
    41     {
    42         for(int i=0;i<n;i++)
    43             scanf("%d",&x[i]);
    44         sort(x,x+n);
    45         double ans=1;
    46         Node tt;
    47         tt.mat[0][0]=p;
    48         tt.mat[0][1]=1-p;
    49         tt.mat[1][0]=1;
    50         tt.mat[1][1]=0;
    51         Node temp;
    52 
    53         temp=pow_M(tt,x[0]-1);
    54         ans*=(1-temp.mat[0][0]);
    55 
    56         for(int i=1;i<n;i++)
    57         {
    58             if(x[i]==x[i-1])continue;
    59             temp=pow_M(tt,x[i]-x[i-1]-1);
    60             ans*=(1-temp.mat[0][0]);
    61         }
    62         printf("%.7f
    ",ans);
    63     }
    64 }
     
  • 相关阅读:
    [转载]各种计算机语言的经典书籍
    [转载]VC 常用快捷键
    [转载]Visual Studio中的debug和release版本的区别
    [转载]Visual C++开发工具与调试技巧整理
    [转载]一个游戏程序员的学习资料
    [转载]C++资源之不完全导引(完整版)
    [转载]一个图形爱好者的书架/白话说学计算机图形学
    [摘录]这几本游戏编程书籍你看过吗?
    Oracle分析函数的使用
    [C/C++]C++下基本类型所占位数和取值范围
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7673860.html
Copyright © 2011-2022 走看看