搞懂了什么是矩阵快速幂优化....
这道题的重点不是DP.
/* 题意: 小明要走某条路,按照个人兴致,向前走一步的概率是p,向前跳两步的概率是1-p,但是地上有地雷,给了地雷的x坐标,(一维),求小明安全到达最后的概率。 思路: 把路分成好多段,小明安全走完每一段的概率乘起来就是答案。 dp[i]=p*dp[i-1]+(1-p)*dp[i-2]; 参考fib数列构造矩阵进行快速幂。 注意初始化的时候,起点概率看作1,起点减一也就是有地雷的地方概率看作0。//屌丝一开始在这里没搞明白。 */ #include<stdio.h> #include<math.h> #include<algorithm> #include<string.h> using namespace std; struct mat { double m[2][2]; }; mat from; double ans[15]; mat mul(mat a,mat b) { mat c; double tmp=0; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { tmp=0; for(int k=0;k<2;k++) { tmp+=a.m[i][k]*b.m[k][j]; } c.m[i][j]=tmp; } } return c; } int jilu[15]; mat calpow(int n) { mat tmp=from; mat ans; memset(ans.m,0,sizeof(ans.m)); ans.m[0][0]=1; ans.m[1][1]=1; while(n) { if(n&1) { ans=mul(ans,tmp); } tmp=mul(tmp,tmp); n/=2; } return ans; } double solve(int n) { mat ttt; ttt=calpow(n); return 1-ttt.m[0][0]; } int main() { int n; double p; while(scanf("%d%lf",&n,&p)!=EOF) { from.m[0][0]=p; from.m[0][1]=1-p; from.m[1][0]=1; from.m[1][1]=0; for(int i=1;i<=n;i++) { scanf("%d",&jilu[i]); } sort(jilu+1,jilu+1+n); ans[1]=solve(jilu[1]-1); for(int i=2;i<=n;i++) { ans[i]=solve(jilu[i]-jilu[i-1]-1);//这里为什么减一以后要注意了 } double rel=1; for(int i=1;i<=n;i++) { rel*=ans[i]; } printf("%.7lf ",rel); } }