Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4410 | Accepted: 1151 |
Description
Input
Each test case contains two lines.
The First line of each test case is N (1 ≤ N ≤ 10) and p (0.25 ≤ p ≤ 0.75) seperated by a single blank, standing for the number of mines and the probability to walk one step.
The Second line of each test case is N integer standing for the place of N mines. Each integer is in the range of [1, 100000000].
Output
Sample Input
1 0.5 2 2 0.5 2 4
Sample Output
0.5000000 0.2500000
/*分析:對於n個地雷s[1],s[2],s[3],s[4]...s[n]
假設s都是不遞減的。
假設dp[i]表示從1到達i這個位置的概率
則:
dp[s[1]-1]爲1~s[1]-1的概率//s[1]不能到達
dp[s[2]-1]爲1~s[2]-1也是1->s[1]-1->s[1]+1->s[2]-1的概率
由於最多隻能跳兩格
所以dp[s[i]+1]一定是從dp[s[i]-1]到達
然後從dp[s[i]+1]到達dp[s[i+1]-1];//這部分就可以用矩陣快速冪
另外根據公式dp[i]=p*dp[i-1]+(1-p)*dp[i-2]也可知從s[i]+1 => s[i+1]-1用矩陣快速冪求
構造初始矩陣:
p 1-p * dp[i] = dp[i+1]
1 0 dp[i-1] dp[i]
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#define INF 99999999
typedef long long LL;
using namespace std;
const int MAX=10+10;
const int N=2;
int n,s[MAX];
double array[N][N],sum[N][N],p;
void InitMatrix(){
array[0][0]=p;
array[0][1]=1-p;
array[1][0]=1;
array[1][1]=0;
for(int i=0;i<N;++i){
for(int j=0;j<N;++j)sum[i][j]=(i == j);
}
}
void MatrixMult(double a[N][N],double b[N][N]){
double c[N][N]={0};
for(int i=0;i<N;++i){
for(int j=0;j<N;++j){
for(int k=0;k<N;++k){
c[i][j]+=a[i][k]*b[k][j];
}
}
}
for(int i=0;i<N;++i)for(int j=0;j<N;++j)a[i][j]=c[i][j];
}
double Matrix(int k){
if(k<0)return 0;//表示s[i-1]~s[i]之間無位置
InitMatrix();//初始化矩陣
while(k){//有k+1個位置,到達第k+1個位置所以是k次
if(k&1)MatrixMult(sum,array);
MatrixMult(array,array);
k>>=1;
}
return sum[0][0];//sum[0][0]*dp[1]+sum[0][1]*dp[0]
}
int main(){
while(~scanf("%d%lf",&n,&p)){
for(int i=1;i<=n;++i)scanf("%d",&s[i]);
sort(s+1,s+1+n);
double ans=Matrix(s[1]-2);//1~s[1]-1的概率
for(int i=2;i<=n;++i){
if(s[i] == s[i-1])continue;
double temp=Matrix(s[i]-s[i-1]-2);//s[i-1]~s[i]之間有s[i]-s[i-1]-1個位置,需要走s[i]-s[i-1]-2次到達最後一個位置
ans=ans*(1-p)*temp;//從s[i-1]-1的位置跳兩格到s[i-1]+1再到s[i]-1
}
printf("%.7f\n",ans*(1-p));//在s[n]-1位置還需要跳兩格才安全了
}
return 0;
}