Scout YYF I
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3723 | Accepted: 928 |
Description
YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. After overcoming a series difficulties, YYF is now at the start of enemy's famous "mine road". This is a very long road, on which there are numbers of mines. At first, YYF is at step one. For each step after that, YYF will walk one step with a probability of
p, or jump two step with a probality of 1-
p. Here is the task, given the place of each mine, please calculate the probality that YYF can go through the "mine road" safely.
Input
The input contains many test cases ended with
EOF.
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].
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
For each test case, output the probabilty in a single line with the precision to 7 digits after the decimal point.
Sample Input
1 0.5 2 2 0.5 2 4
Sample Output
0.5000000 0.2500000
Source
題意:在一條不滿地雷的路上,你現在的起點在1處。在N個點處布有地雷,1<=N<=10。地雷點的坐標范圍:[1,100000000].
每次前進p的概率前進一步,1-p的概率前進1-p步。問順利通過這條路的概率。就是不要走到有地雷的地方。
設dp[i]表示到達i點的概率,則 初始值 dp[1]=1.
很容易想到轉移方程: dp[i]=p*dp[i-1]+(1-p)*dp[i-2];
但是由於坐標的范圍很大,直接這樣求是不行的,而且當中的某些點還存在地雷。
N個有地雷的點的坐標為 x[1],x[2],x[3]```````x[N].
我們把道路分成N段:
1~x[1];
x[1]+1~x[2];
x[2]+1~x[3];
`
`
`
x[N-1]+1~x[N].
這樣每一段只有一個地雷。我們只要求得通過每一段的概率。乘法原理相乘就是答案。
對於每一段,通過該段的概率等於1-踩到該段終點的地雷的概率。
就比如第一段 1~x[1]. 通過該段其實就相當於是到達x[1]+1點。那么p[x[1]+1]=1-p[x[1]].
但是這個前提是p[1]=1,即起點的概率等於1.對於后面的段我們也是一樣的假設,這樣就乘起來就是答案了。
對於每一段的概率的求法可以通過矩陣乘法快速求出來。
代碼:
/* POJ 3744 C++ 0ms 184K */ #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<math.h> 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 x[30]; int main() { int n; double p; while(scanf("%d%lf",&n,&p)!=EOF)//POJ上G++要改為cin輸入 { for(int i=0;i<n;i++) scanf("%d",&x[i]); sort(x,x+n); double ans=1; Matrix tt; tt.mat[0][0]=p; tt.mat[0][1]=1-p; tt.mat[1][0]=1; tt.mat[1][1]=0; Matrix temp; temp=pow_M(tt,x[0]-1); ans*=(1-temp.mat[0][0]); for(int i=1;i<n;i++) { if(x[i]==x[i-1])continue; temp=pow_M(tt,x[i]-x[i-1]-1); ans*=(1-temp.mat[0][0]); } printf("%.7lf\n",ans);//POJ上G++要改為%.7f } return 0; }