标签:.net ges its walk single poj series cas case
Input
Output
Sample Input
1 0.5 2 2 0.5 2 4
Sample Output
0.5000000 0.2500000
一位童子兵要穿过一条路,路上有些地方放着地雷。这位童子兵非常好玩,走路一蹦一跳的。
每次他在 i 位置有 p 的概率走一步到 i+1 ,或者 (1-p) 的概率跳一步到 i+2。童子兵初始在1位置,求他安全通过这条道路的概率。
以所在位置为状态,dp[i] 表示在位置 i 的安全的概率。
dp[i] = p * dp[i-1] + (1 - p) * dp[i-2]; // i 位置没有地雷
但是题目数据的范围是 10^8 这样dp的话会 TLE。
想想可以用矩阵快速幂优化。简单推出矩阵是
|p 1-p| * |dp[i] | = |dp[i+1]|
|1 0 | |dp[i-1]| |dp[i] |
而这时地雷位置是不满足这个矩阵的,因此我们得对地雷位置进行特判。而两个地雷中间的位置可以用快速幂优化。
假设 k 位置放有地雷,,我们可以得到 dp[k+1] = dp[k-1] * (1 - p);
对于炸弹位置为 a[i] 和 a[i+1] 之间的数,知道 dp[a[i]+1] 后可以推出
(视0位置有颗地雷,有地雷的位置的dp值为0)
于是我们可以对两个前后两个地雷之间用快速幂优化,并最终得到答案dp[max(a[i])+1];
转自:http://blog.csdn.net/xuelanghu407/article/details/47172759
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cmath> 6 using namespace std; 7 8 int n;double p; 9 int x[30]; 10 11 struct Node{double mat[2][2];}; 12 Node mul(Node a,Node b) 13 { 14 Node res; 15 for(int i=0;i<2;i++) 16 for(int j=0;j<2;j++) 17 { 18 res.mat[i][j]=0; 19 for(int k=0;k<2;k++) res.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; 20 } 21 return res; 22 } 23 Node pow_M(Node a,int n) 24 { 25 Node res; 26 memset(res.mat,0,sizeof(res.mat)); 27 for(int i=0;i<2;i++) 28 res.mat[i][i]=1; 29 Node temp=a; 30 while(n) 31 { 32 if(n&1)res=mul(res,temp); 33 temp=mul(temp,temp); 34 n>>=1; 35 } 36 return res; 37 } 38 int main() 39 { 40 while(~scanf("%d%lf",&n,&p)) 41 { 42 for(int i=0;i<n;i++) 43 scanf("%d",&x[i]); 44 sort(x,x+n); 45 double ans=1; 46 Node tt; 47 tt.mat[0][0]=p; 48 tt.mat[0][1]=1-p; 49 tt.mat[1][0]=1; 50 tt.mat[1][1]=0; 51 Node temp; 52 53 temp=pow_M(tt,x[0]-1); 54 ans*=(1-temp.mat[0][0]); 55 56 for(int i=1;i<n;i++) 57 { 58 if(x[i]==x[i-1])continue; 59 temp=pow_M(tt,x[i]-x[i-1]-1); 60 ans*=(1-temp.mat[0][0]); 61 } 62 printf("%.7f\n",ans); 63 } 64 }
POJ3744 Scout YYF I (矩阵优化的概率DP)
标签:.net ges its walk single poj series cas case
原文地址:http://www.cnblogs.com/fengzhiyuan/p/7673860.html