poj 3744 特征方程+快速幂

容易得到:dp[n] = dp[n - 1] * p + dp[n - 2] * ( 1 - p );  (1)

如果在位置i有雷的话,则:dp[i + 1] = dp[i - 1] * ( 1 - p );

如何求得dp[i]呢?

我们可以解特征方程(1),得到:

  dp[n] = a * ( p - 1 ) ^ ( n - 1 ) + b;

  求得a和b后,再做快速幂。

我们也可以直接用矩阵快速幂来求得答案。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int N = 11;
 8 int mine[N];
 9 int n;
10 double a, b, p;
11 
12 double quickPow( double d, int m )
13 {
14     double ans = 1.0, w = d;
15     while ( m )
16     {
17         if ( m & 1 )
18         {
19             ans = ans * w;
20         }
21         w = w * w;
22         m = m >> 1;
23     }
24     return ans;
25 }
26 
27 double dp( int n )
28 {
29     if ( n == 0 ) return 0;
30     return a * quickPow( p - 1, n - 1 ) + b;
31 }
32 
33 int main ()
34 {
35     while ( scanf("%d%lf", &n, &p) != EOF )
36     {
37         a = ( p - 1.0 ) / ( p - 2.0 );
38         b = 1.0 / ( 2 - p );
39         for ( int i = 0; i < n; i++ )
40         {
41             scanf("%d", mine + i);
42         }
43         sort( mine, mine + n );
44         double ans = 1.0;
45         int cur = 1;
46         for ( int i = 0; i < n; i++ )
47         {
48             int dis = mine[i] - cur;
49             ans = ans * dp(dis) * ( 1 - p );
50             cur = mine[i] + 1;
51         }
52         printf("%.7f
", ans);
53     }
54     return 0;
55 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4657193.html