hdu-5015-233 Matrix-矩阵 (矩阵快速幂)(dp)

渐渐有点理解矩阵的含义了

多刷多思考!

主要是利用矩阵来转移状态,通过矩阵乘法来得出结果,要先推出矩阵的转移形式

之后的乘法和快速幂就很套路了。

#include
#include
#include
using namespace std;

const int mod = 1e7+7;
int n,m;

struct matrix { //定义矩阵结构体并且初始化数组
    long long m[15][15]; //注意要定义为long long ,不然会爆
    matrix() {
        memset(m,0,sizeof(m));
    }
};

matrix mul(matrix a,matrix b) { //矩阵乘法
    matrix tmp;
    for(int i = 1;i <= n+2;i++) {
        for(int j = 1;j <= n+2;j++) {
            for(int k = 1;k <= n+2;k++) {
                tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % mod; //每次取模
            }
        }
    }
    return tmp;
}

matrix powmul(matrix a,int x) { //矩阵快速幂
    matrix tmp;
    for(int i = 1;i <= n+2;i++)
        tmp.m[i][i] = 1; //别忘记定义单位矩阵!
    while(x) {
        if(x & 1)
            tmp = mul(tmp,a);
        a = mul(a,a);
        x >>= 1;
    }
    return tmp;
}

void pi(matrix x) {
    for(int i = 1;i <= n+2;i++) {
        for(int j = 1;j <= n+2;j++) {
            printf("%d ",x.m[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main() {
    while(scanf("%d%d",&n,&m) != EOF) {
        matrix ans,base; //如果是使用结构体内部函数初始化数组的话要在main函数内定义变量,这样才能每次都初始化结构体内的数组
        ans.m[1][1] = 23;
        for(int i = 2;i <= n+1;i++)
            scanf("%lld",&ans.m[i][1]);
        ans.m[n+2][1] = 3;
        for(int i = 1;i <= n+1;i++)
            base.m[i][1] = 10;
        for(int i = 1;i <= n+2;i++)
            base.m[i][n+2] = 1;
        for(int i = 2;i <= n+1;i++)
            for(int j = 2;j <= i;j++)
                base.m[i][j] = 1;
        base = powmul(base,m);
        ans = mul(base,ans);
        //pi(ans); //输出检查结果
        //pi(base);
        printf("%lld\n",ans.m[n+1][1]);
    }
    return 0;
}


你可能感兴趣的:(矩阵快速幂)