POJ 3744 Scout YYF I (矩陣相乘+概率DP)
阿新 • • 發佈:2019-02-03
題面:
Time Limit: 1000MS | Memory Limit: 65536K |
Total Submissions: 7254 | Accepted: 2118 |
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 pInput
The input contains many test cases ended with EOF.Each test case contains two lines.
The First line of each test case is N
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
題目大意:
一條路上有n個雷,走一步的可能性是p,走兩步的可能性是1-p,起點為1,求安全抵達n的概率。
題目分析:
矩陣相乘的題目,
如果k號位有雷,那麼安全通過這個雷只可能是在k-1號位選擇走兩步到k+1號位。因此,可以得到如下結論:在第i個雷的被處理掉的概率就是從a[i-1]+1號位到a[i]號位的概率。於是,可以用1減去就可以求出安全通過第i個雷的概率,最後乘起來即可,但是由於資料很大,所以需要用到矩陣快速冪,類似斐波那契數列,有ans[i]=p*ans[i-1]+(1-p)*ans[i-2],構造矩陣為:
程式碼實現:
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int n;
double p;
int a[20];
double b[5][5];
double s[5];
double tmp[5][5];
double temp[5];
double Count(int t)
{
b[0][0]=p;
b[0][1]=1-p;
b[1][0]=1;
b[1][1]=0;
s[0]=1;
s[1]=0;
while(t!=0)
{
if(t%2==1)
{
for(int i=0;i<2;i++)
{
temp[i]=0;
for(int j=0;j<2;j++)
{
temp[i]+=b[i][j]*s[j];
}
}
for(int i=0;i<2;i++)
{
s[i]=temp[i];
}
}
t/=2;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
tmp[i][j]=0;
for(int k=0;k<2;k++)
{
tmp[i][j]+=b[i][k]*b[k][j];
}
}
}
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
b[i][j]=tmp[i][j];
}
}
}
return s[0];
}
int main()
{
double ans=0;
while(scanf("%d%lf",&n,&p)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[0]=0;
sort(a,a+n+1);
ans=1;
for(int i=0;i<n;i++)
{
ans=ans*(1-Count(a[i+1]-a[i]-1));
}
printf("%.7lf\n",ans);
}
return 0;
}