POJ 3744 【矩阵快速幂优化 概率DP】

搞懂了什么是矩阵快速幂优化....

这道题的重点不是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);
    }
}
原文地址:https://www.cnblogs.com/tun117/p/5054654.html