poj 3744 概率dp 快速幂 注意排序 难度:2

/*
Scout YYF I
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5304   Accepted: 1455

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].

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
*/
/*
思路:
1.因为只有两种转移方式,即向前跳一步(p)或者向前跳两步(1-p),所以转移是单向的,
转移方程:dp[i]=dp[i-1]*p+dp[i-2]*(1-p),如果是踩到地雷的情况就不能再继续转移了,加入答案中
2.最多走1e8,也就转移1e8下,但是还是悬在边界上,因为n小,步数小,用快速幂增加速度
3.注意排序,在这里被坑了
*/

#include <cstdio> #include <algorithm> using namespace std; int lame[11]; void copy(double des[2][2],double src[2][2]){ des[0][0]=src[0][0];des[0][1]=src[0][1];des[1][0]=src[1][0];des[1][1]=src[1][1]; } void multi(double l[2][2],double r[2][2],double ans[2][2]){ double temp[4]; temp[0]=l[0][0]*r[0][0]+l[0][1]*r[1][0]; temp[1]=l[0][0]*r[0][1]+l[0][1]*r[1][1]; temp[2]=l[1][0]*r[0][0]+l[1][1]*r[1][0]; temp[3]=l[1][0]*r[0][1]+l[1][1]*r[1][1]; ans[0][0]=temp[0];ans[0][1]=temp[1];ans[1][0]=temp[2];ans[1][1]=temp[3]; } void pow(double pro[2][2],double faim[2][2],int times){ double base[2][2] ; copy(base,pro); while(times>0){ if((times&1)==1)multi(base,faim,faim); multi(base,base,base); times>>=1; } } int main(){ int n; double p; while(scanf("%d",&n)==1){ scanf("%lf",&p); for(int i=0;i<n;i++)scanf("%d",lame+i); sort(lame,lame+n); double faim[2][2];faim[1][0]=faim[0][1]=faim[1][1]=0;faim[0][0]=1; double pro[2][2];pro[0][0]=p;pro[0][1]=1-p;pro[1][0]=1;pro[1][1]=0; int f=1; for(int i=0;i<n;i++){ pow(pro,faim,lame[i]-f); faim[0][0]=0; f=lame[i]; } faim[1][0]*=(1-p); printf("%.7f\n",faim[1][0]); } return 0; }

  

posted @ 2014-11-05 01:17  雪溯  阅读(154)  评论(0编辑  收藏  举报