矩阵快速幂应用于概率DP POJ 3744

来源:互联网 发布:淘宝买家退货率 编辑:程序博客网 时间:2024/05/16 06:36

第一次构造了2*2的矩阵,不成功:

matrix[2][2]={p,1.0,1.0-p,0}

#include<cctype>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<queue>#include<stack>#include<set>#include<map>#define CLEAR(a) memset((a),0,sizeof((a)))using namespace std;typedef long long LL;const double pi = acos(-1.0);const int maxn=1e4;const int inf=99999999;const float eps=1e-3;vector<int> vec;double f[maxn];struct Matrix{    double x00,x01,x10,x11;    Matrix(){};    Matrix(double x00,double x01,double x10,double x11)    {        this->x00=x00;        this->x01=x01;        this->x10=x10;        this->x11=x11;    }    Matrix(double p)    {        this->x00=p;        this->x01=1.0;        this->x10=1.0-p;        this->x11=0;    }    double GetResult()    {        return this->x11;    }};    Matrix operator*(const Matrix& a,const Matrix &b)    {        return Matrix(a.x00*b.x00+a.x01*b.x10,a.x00*b.x01+a.x01*b.x11,a.x10*b.x00+a.x11*b.x10,a.x10*b.x01+a.x11*b.x11);    }    Matrix operator^(const Matrix& a,int n)    {        if (n==1) return a;        else if (n&1) return (a^((n-1)>>1))*(a^((n+1)>>1));        else return (a^(n>>1))*(a^(n>>1));    }int main(){    int n;    double p;    while (~scanf("%d%lf",&n,&p))    {        vec.clear();        CLEAR(f);        for(int i=0;i<n;i++)        {            int x;            scanf("%d",&x);            vec.push_back(x);        }        sort(vec.begin(),vec.end());        for(int i=0;i<n;i++)        {            if (i>0)            {                Matrix m(f[i-1]);                f[i]=(m^(vec[i]-vec[i-1])).GetResult();            }            else            {                Matrix m(1);                f[i]=(m^(vec[i]-1)).GetResult();            }        }        printf("%.7lf",f[*vec.end()]);    }    return 0;}



第二次,用到了单位矩阵:

{1,0,0,1}

#include<cctype>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<queue>#include<stack>#include<set>#include<map>#define CLEAR(a) memset((a),0,sizeof((a)))using namespace std;const double eps = 1e-8;const double pi = acos(-1.0);typedef long long LL;const int maxn = 15;int m = 2;int mine[maxn];class Matrix{    public:        double num[3][3];        Matrix()        {            CLEAR(num);        }        Matrix(double p)        {            CLEAR(num);            num[0][0] = p;            num[0][1] = 1 - p;            num[1][0] = 1;            num[1][1] = 0;        }        static Matrix One()        {            Matrix res;            res.num[0][0] = 1;            res.num[1][1] = 1;            return res;        }        Matrix operator*(const Matrix& b)        {            Matrix a = *this, ans;            for (int i = 0; i < m; i++)                for (int j = 0; j < m; j++)                    for (int k = 0; k < m; k++)                    {                        ans.num[j][k] += a.num[j][i] * b.num[i][k];                    }            return ans;        }        Matrix operator*= (const Matrix& b)        {            *this = *this * b;            return *this;        }};Matrix pow(Matrix matrix, int n){    Matrix res = Matrix::One();    while (n)    {        if (n & 1)        {            res *= matrix;        }        matrix *= matrix;        n >>= 1;    }    return res;}double getRes(int t, double p){    if (t <= 1)    {        return 0;    }    if (t == 2)    {        return 1;    }    if (t == 3)    {        return p;    }    t -= 3;    Matrix matrix(p);    matrix = pow(matrix, t);    return matrix.num[0][0] * p + matrix.num[0][1];}int main(){    int n;    double p;    while (~scanf("%d%lf", &n, &p))    {        mine[0] = 0;        for (int i = 1; i <= n; i++)        {            scanf("%d", mine + i);        }        sort(mine + 1, mine + n + 1);        double ans = 1;        for (int i = 1; i <= n; i++)        {            ans *= getRes(mine[i] - mine[i - 1], p);            ans *= 1.0 - p;        }        printf("%.7lf\n", ans);    }    return 0;}


0 0