POJ 3744 Scout YYF I 简单递推

26 篇文章 0 订阅

题意就是

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



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值