参考:
http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710586.html
此题是一个用矩阵优化的求概率的题目。
主要思想是分段,根据转移方程用矩阵求解。
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-9;
const int MAXN=110;
struct Matrix{
double mat[MAXN][MAXN];
int n;
Matrix () {}
Matrix (int x, double v = 0)
{
n = x;
REP(i, x) REP(j, x)
mat[i][j] = i == j ? v : 0;
}
Matrix operator * (const Matrix &b) const
{
Matrix ret = Matrix(n);
REP(i, n) REP(j, n) REP(r, n)
{
ret.mat[i][j] = (ret.mat[i][j] + mat[i][r] * b.mat[r][j]);
}
return ret;
}
} ;
Matrix pow_M(Matrix a, int n)
{
Matrix ret = Matrix(a.n, 1);
Matrix temp = a;
while (n)
{
if (n & 1) ret = ret * temp;
temp = temp * temp;
n >>= 1;
}
return ret;
}
int n;
double p;
int a[12];
void solve()
{
Matrix e = Matrix(2);
e.mat[0][0] = p;
e.mat[0][1] = 1 - p;
e.mat[1][0] = 1.0;
e.mat[1][1] = 0.0;
Matrix x = Matrix(2);
x.mat[1][0] = 1.0;
FED(i, n - 2, 0)
{
int d = a[i + 1] - a[i] - 1;
Matrix y = pow_M(e, d);
x = y * x;
x.mat[1][0] = x.mat[0][0];
x.mat[0][0] = 0;
}
int d = a[0] - 1;
Matrix y = pow_M(e, d);
x = y * x;
printf("%.7lf\n", x.mat[0][0]);
}
//void solve()
//{
//
// Matrix e = Matrix(2);
// e.mat[0][0] = p;
// e.mat[0][1] = 1 - p;
// e.mat[1][0] = 1.0;
// e.mat[1][1] = 0.0;
// Matrix tmp;
// tmp = pow_M(e, a[0] - 1);
// double ans = 1.0;
// ans *= (1 - tmp.mat[0][0]);
// for (int i = 1; i < n; i++)
// {
// tmp = pow_M(e, a[i] - a[i - 1] - 1);
// ans *= (1 - tmp.mat[0][0]);
// }
// printf("%.7lf\n", ans);
//}
int main ()
{
while (~scanf("%d %lf", &n, &p))
{
REP(i, n) RI(a[i]);
int fla = 0;
REP(i, n)
if (a[i] == 1)
{
printf("0.0000000\n");
fla = 1;
break;
}
if (fla) continue;
sort(a, a + n);
solve();
}
return 0;
}