矩阵的的初步认识

来源:互联网 发布:涉税软件下载 编辑:程序博客网 时间:2024/06/07 03:56

矩阵的乘法运算

这里写图片描述
这里写图片描述

typedef vector<int> vitypedef vector<vi> matmat mul(mat A,mat B){    mat C(sz(A),vi(sz(B[0]));    for(int i=0;i<sz(A);i++)        for(int k=0;k<sz(B);k++)            for(int j=0;j<sz(B[0];j++)                C[i][j]+=A[i][k]*B[k][j];    return C;}

基本性质

乘法结合律: (AB)C=A(BC)
乘法左分配律:(A+B)C=AC+BC
乘法右分配律:C(A+B)=CA+CB
对数乘的结合性k(AB)=(kA)B=A(kB)
矩阵乘法一般不满足交换律

应用

<1>例如我们要求斐波那契数列的第x项;
我们可以这样构造
这里写图片描述
有由于乘法结合律所以
这里写图片描述

typedef vector<int> vitypedef vector<vi> matmat mul(mat A,mat B){    mat C(sz(A),vi(sz(B[0]));    for(int i=0;i<sz(A);i++)        for(int k=0;k<sz(B);k++)            for(int j=0;j<sz(B[0];j++)                C[i][j]=1ll*C[i][j]+A[i][k]*B[k][j]%P;    return C;}mat pow(mat A,int n){    mat C(sz(A),vi(sz(A[0])));    for(int i=0;i<sz(A);i++)C[i][i]=1;//相当于{1}    while(n){        if(n&1)C=mul(A,C);        A=mul(A,A);        n>>=1;    }return C;  }int  solve(){    mat(2,vi(2));    A[0][0]=1;A[0][1]=1;    A[1][0]=1;A[1][1]=0;    A=pow(A,n-1);    return A[0][0];}

<2>题意:在一条满是地雷的路上,起点在1处。在N个点处布有地雷,1<=N<=10。地雷点的坐标范围每次前进p的概率前进一步,1-p的概率前进2步。问顺利通过这条路的概率。n<18
我们可以把路分成n段即
1~pos[1];
pos[1]+1~pos[2];
pos[2]+1~pos[3];

对于每一段我们一步一步的DP
dp[i]表示走到第i处的可能性
于是可以成功通过这一段的可能性为1dp[pos[i]]

#include<stdio.h>#include<algorithm>#include<iostream>using namespace std;struct mat{    double Mat[2][2];    mat(){Mat[0][1]=Mat[0][0]=Mat[1][0]=Mat[1][1]=0;}    mat operator *(const mat&A)const{        mat B;        for(int i=0;i<2;i++)            for(int k=0;k<2;k++)                for(int j=0;j<2;j++)                    B.Mat[i][j]+=A.Mat[i][k]*Mat[k][j];        return B;    }};mat pow(mat a,int n){    mat ret;    for(int i=0;i<2;i++)ret.Mat[i][i]=1;    while(n){        if(n&1)ret=ret*a;        a=a*a;        n>>=1;    }return ret;}int x[30],n;int main(){    double p;    while(~scanf("%d",&n)){        cin>>p;        for(int i=1;i<=n;i++)scanf("%d",x+i);        sort(1+x,1+x+n);        double ans=1;        mat tt,nw,tmp;        tt.Mat[0][0]=p;        tt.Mat[0][1]=1-p;        tt.Mat[1][0]=1;        nw.Mat[0][0]=1;        for(int i=1;i<=n;i++){            if(x[i]==x[i-1])continue;            tmp=pow(tt,x[i]-x[i-1]-1);            tmp=nw*tmp;            ans*=(1-tmp.Mat[0][0]);        }        printf("%.7f\n",ans);    }    return 0;}
1 0
原创粉丝点击