题目大意
给定N(1≤N≤10)个地雷的位置,给定一个概率p(p∈[0.25,0.75])。规定有p的概率向前走一步、
(1−p) 的概率向前走两步。求从1开始走安全走完雷区的概率。
这道题是在一次培训时讲的例题。当时是作为概率动归讲的。但我看到
关键是下边这段:
double f = 1;
for (int i = 1;i <= N;i ++)
{
int k = a[i] - a[i - 1] - 1;
f *= (1 - quickpow(p - 1, k)) / (2 - p) * (1 - p);
}
将雷区分为许多段,每段为两个雷之间无雷的区域。之后便能递推得出结果。
众所周知,等比数列求和为a1(1−pn)1−p,所以在pn处我们可以用矩阵加速(尽管我认为没啥必要…)。
那个(2−p)是化简[1−(p−1)]的结果。
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int a[12];
double quickpow(double p, int k)
{
double ans = 1;
while (k)
{
if (k & 1) ans *= p;
p *= p;
k >>= 1;
}
return ans;
}
int main()
{
int N;
double p;
while (scanf("%d%lf", &N, &p) != EOF)
{
memset(a, 0, sizeof a);
double f = 1;
for (int i = 1;i <= N;i ++)
scanf("%d", &a[i]);
sort(a + 1, a + N + 1);
for (int i = 1;i <= N;i ++)
{
int k = a[i] - a[i - 1] - 1;
f *= (1 - quickpow(p - 1, k)) / (2 - p) * (1 - p);
}
printf("%.7lf\n", f);
}
}

1022

被折叠的 条评论
为什么被折叠?



