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

 
(Another) 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, (Another) 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, (Another) YYF is at step one. For each step after that, (Another) 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 (Another) 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

  首先表示我被黑了。。出题人好过分。。简直跟我有仇,不仅黑了一道题,而且还黑了一套题。。

  题目大意 另一个叫做yyf的人在一个数轴上,他在位置1,每次他有p的概率向右跳1格,有(1 - p)的概率向右跳2格,如果踩到地雷就死了,问生还的概率。

  显然动态规划。当位置i没有地雷的时候,显然有

  如果位置i有地雷,那么有

  由于值域很大,所以按照递推式动态规划的通用套路:构建转移矩阵加快动态规划。

  由于n很小,所以可以分段,段内用矩阵快速幂处理,然后特殊处理一下f[i],继续往前。

  现在来构建转移矩阵:

 Code

  1 /**
  2  * poj
  3  * Problem#3744
  4  * Accepted
  5  * Time: 0ms
  6  * Memory: 232k 
  7  */
  8 #include <iostream>
  9 #include <fstream>
 10 #include <sstream>
 11 #include <cstdio>
 12 #include <cstdlib>
 13 #include <cstring>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cctype>
 17 #include <algorithm>
 18 #include <set>
 19 #include <map>
 20 #include <vector>
 21 #include <queue>
 22 #include <stack>
 23 #include <bitset>
 24 #include <cassert>
 25 #ifndef WIN32
 26 #define Auto "%lld"
 27 #else
 28 #define Auto "%I64d"
 29 #endif
 30 using namespace std;
 31 typedef bool boolean;
 32 #define clra(a) memset(a, false, sizeof(a))
 33 const signed int inf = ((~0u) >> 1);
 34 #define smin(a, b) a = min(a, b)
 35 #define smax(a, b) a = max(a, b)
 36 
 37 template <typename T>
 38 class Matrix {
 39     public:
 40         T a[2][2];
 41         int row; 
 42         int col;
 43         
 44         Matrix() {        }
 45         Matrix(int row, int col):row(row), col(col) {        }
 46         
 47         Matrix<T> operator * (Matrix<T> b) {
 48             Matrix<T> rt(row, b.col);
 49             assert(col == b.row);
 50             for(int i = 0; i < row; i++)
 51                 for(int j = 0; j < b.col; j++) {
 52                     rt[i][j] = 0;
 53                     for(int k = 0; k < col; k++)
 54                         rt[i][j] += a[i][k] * b[k][j];
 55                 }
 56             return rt;
 57         } 
 58         
 59         T* operator [] (int pos) {
 60             return &a[pos][0];
 61         }
 62 };
 63 
 64 int n;
 65 double p;
 66 Matrix<double> unit(2, 2);
 67 Matrix<double> trans(2, 2);
 68 int boom[15];
 69 
 70 template <typename T>
 71 Matrix<T> matpow(Matrix<T>& a, int pos) {
 72     if(pos == 0)    return unit;
 73     if(pos == 1)    return a;
 74     Matrix<T> temp = matpow(a, pos >> 1);
 75     temp = temp * temp;
 76     if(pos & 1)    temp = temp * a;
 77     return temp;
 78 }
 79 
 80 inline void prepare() {
 81     unit[0][0] = unit[1][1] = 1;
 82     unit[0][1] = unit[1][0] = 0;
 83 }
 84 
 85 inline void init() {
 86     for(int i = 0; i < n; i++)
 87         scanf("%d", boom + i);
 88     sort(boom, boom + n);
 89     trans[0][0] = p, trans[0][1] = 1 - p;
 90     trans[1][0] = 1, trans[1][1] = 0;
 91 }
 92 
 93 inline void solve() {
 94     int last = boom[n - 1];
 95     Matrix<double> f(2, 1);
 96     f[0][0] = 0, f[1][0] = 1;
 97     for(int i = n - 2; ~i; f[0][0] = 0, last = boom[i], i--)
 98         f = matpow(trans, last - boom[i]) * f;
 99     f = matpow(trans, last - 1) * f;
100     printf("%.7lf\n", f[0][0]);
101 }
102 
103 int main() {
104     prepare();
105     while(~scanf("%d%lf", &n, &p)) {    //坑啊,scanf交G++ WA了,交C++过了 
106         init();
107         solve();
108     }
109     return 0;
110 }

 

转载于:https://www.cnblogs.com/yyf0309/p/7498802.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值