题意就是
一个人, 站在坐标为1的点处,然后每次走路有p的概率一下走出去坐标1,1-p的概率一下走出去坐标2
路上某些点(n < 10)有雷,问这个人最终迈过这些雷不被炸的概率是多大
想一下就知道这些雷之间实际上是独立不相关的
可以分段考虑
然后互相之间乘一下就行
假设有个雷在x点
现在人在坐标1
然后不踩雷就得从1点到x-1点
并且从x-1点迈出坐标2到x+1
从x-1迈出坐标2到x+1的概率是1-p
之前1到x-1这段是没有任何雷的。就可以进行普通的递推了
a_n = a_(n-1) * p + a_(n-2) * (1-p)
这个我们可以用矩阵乘法
或者求出通项
a_n - a_(n-1) * p -a_(n-2) * (1-p) = 0
特征方程是n^2 - p *n - (1-p) = 0
求出两个解,1, p - 1
a_n = A + B * (p - 1) ^ n
带入a_0 = 1 , a_1 = p
得a_n = 1/(2-p) + (1-p) / (2-p) * (p - 1 ) ^n
即可
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <algorithm> #include <map> #include <ctime> #define MAXN 222222 #define MAXM 222222 #define INF 1000000001 using namespace std; double p; int n; int a[15]; double ans; double getan(int x) { return 1.0 / (2.0 - p) + (1.0 - p) / (2.0 - p) * pow(p - 1.0, x); } int main() { while(scanf("%d%lf", &n, &p) != EOF) { for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a + n); int now = 1; ans = 1; for(int i = 0; i < n; i++) { int nxt = a[i]; if(a[i] >= now + 1) { int dis = a[i] - now - 1; ans = ans * getan(dis) * (1.0 - p); now = a[i] + 1; } else { ans = 0; break; } } printf("%.7f\n", ans); } return 0; }
时间: 2024-11-11 01:02:35