题意就是
一个人, 站在坐标为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;
}