容易得到: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\n", ans); 53 } 54 return 0; 55 }
时间: 2024-10-19 20:09:29