0
点赞
收藏
分享

微信扫一扫

POJ 3744 Scout YYF I——概率dp+分段矩阵快速幂

楠蛮鬼影 2022-08-17 阅读 42


题意:

给出n个障碍的坐标,规定玩家一开始在坐标1处,每次有概率p前进1个单位,有概率1-p前进两个单位,问越过所有障碍的概率

思路:

定义dp[i]为到达坐标i的概率,那么dp[i] = c[i] * (dp[i-1]+dp[i-2]),c[i]表示坐标i是否有障碍

这个式子可以用分段矩阵快速幂优化,首先将坐标分成n段:

0~a[1]

a[1]+1~a[2]

......

a[n-1]+1~a[n]

对于每一段要求的是(1-达到a[i])的概率,然后把这n段的结果相乘就是答案

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct Matrix { double m[2][2]; } matrix;
Matrix mul(Matrix m1, Matrix m2) {
Matrix ans;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
ans.m[i][j] = 0;
for (int k = 0; k < 2; k++) ans.m[i][j] += m1.m[i][k] * m2.m[k][j];
}
}
return ans;
}
Matrix mpow(Matrix m, int n) {
Matrix ans;
ans.m[0][0] = 1, ans.m[0][1] = 0;
ans.m[1][0] = 0, ans.m[1][1] = 1;
while (n) {
if (n & 1) ans = mul(ans, m);
m = mul(m, m);
n >>= 1;
}
return ans;
}
int main() {
int n, a[20];
double p;
while (~scanf("%d%lf", &n, &p)) {
a[0] = 0;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
sort(a+1, a+1+n);
n = unique(a+1, a+1+n)-(a+1);
matrix.m[0][0] = p, matrix.m[0][1] = 1-p;
matrix.m[1][0] = 1, matrix.m[1][1] = 0;
double ans = 1;
for (int i = 1; i <= n; i++) {
Matrix res = mpow(matrix, a[i]-a[i-1]-1);
ans *= (1 - res.m[0][0]);
}
printf("%.7f\n", ans);
}
return 0;
}

 

举报

相关推荐

0 条评论