POJ 3744 概率dp

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
struct Matrix
{
	double mat[2][2];
};
Matrix mul(Matrix a, Matrix b)
{
	Matrix ret;
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 2; j++)
		{
			ret.mat[i][j] = 0;
			for (int k = 0; k < 2; k++)
				ret.mat[i][j] += a.mat[i][k] * b.mat[k][j];
		}
	return ret;
}
Matrix pow_M(Matrix a, int n)
{
	Matrix ret;
	memset(ret.mat, 0, sizeof(ret.mat));
	for (int i = 0; i < 2; i++)ret.mat[i][i] = 1;
	Matrix temp = a;
	while (n)
	{
		if (n & 1)ret = mul(ret, temp);
		temp = mul(temp, temp);
		n >>= 1;
	}
	return ret;
}
int inp[30], n;
double p;
int main(int argc, char const *argv[])
{
	while (~scanf("%d%lf", &n, &p) && n)
	{
		for (int i = 0; i < n; i++)
			scanf("%d", inp + i);
		sort(inp, inp + n);
		double ans = 1;
		Matrix t, tmp;
		t.mat[0][0] = p, t.mat[0][1] = 1 - p, t.mat[1][0] = 1, t.mat[1][1] = 0;
		tmp = pow_M(t, inp[0] - 1);
		ans *= (1 - tmp.mat[0][0]);
		for (int i = 1; i < n; i++)
			if (inp[i] != inp[i - 1])
				tmp = pow_M(t, inp[i] - inp[i - 1] - 1), ans *= (1 - tmp.mat[0][0]);
		printf("%.7lf\n", ans);
	}
	return 0;
}

 dp[i]=p*dp[i-1]+(1-p)*dp[i-2];

但存在地雷,用类似离散化的思路,分成N段,每段一个地雷,求得每一段的概率,相乘就是答案。

你可能感兴趣的:(POJ 3744 概率dp)