题意:每次走一步的概率是p,走两步的概率是1-p,然后有n个点上有地雷。问YYF走过雷区的概率是多少
思路: dp[i]=p*dp[i-1]+(1-p)dp[i-2]
转移矩阵:
ans[i] | p ,1-p | ans[i-1]
=| | *
ans[i-1] | 1 , 0 | ans[i-2]
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; template <class T> inline bool rd(T &ret) { char c; int sgn; if(c = getchar() , c == EOF) return false; while(c != '-' && (c < '0' || c > '9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return true; } const int N = 11; struct Matrix { int r, c; double val[N][N]; void clear() { memset(val, 0, sizeof(val)); } void One() { for (int i = 0; i < r; ++i) val[i][i] = 1; } }; Matrix multi(Matrix a, Matrix b) { Matrix re; re.r = a.r, re.c = b.c; re.clear(); for (int i = 0; i < re.r; ++i) for (int j = 0; j < re.c; ++j) for (int k = 0; k < a.c; ++k) re.val[i][j] = re.val[i][j] + (a.val[i][k] * b.val[k][j]); return re; } Matrix Pow(Matrix a, int x) { Matrix re; re.clear(); re.r = re.c = a.r; re.One(); while (x > 0) { if (x & 1) re = multi(re, a); a = multi(a, a); x >>= 1; } return re; } int n; int pos[N]; double p; int main() { while (2 == scanf("%d%lf", &n, &p)) { for (int i = 0; i < n; ++i) rd(pos[i]); sort(pos, pos + n); double ans = 1; Matrix now; now.r = now.c = 2; now.val[0][0] = p, now.val[0][1] = 1 - p; now.val[1][0] = 1, now.val[1][1] = 0; Matrix get = Pow(now, pos[0] - 1); ans *= 1 - get.val[0][0]; for (int i = 1; i < n; ++i) { if (pos[i] == pos[i - 1]) continue; get = Pow(now, pos[i] - pos[i - 1] - 1); ans *= 1 - get.val[0][0]; } printf("%.7f\n", ans); } return 0; }