欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

233 Matrix HDU - 5015(矩阵快速幂)

程序员文章站 2022-03-16 18:25:59
...

233 Matrix HDU - 5015

In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 … in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be 233, 2333, 23333… (it means a 0,1 = 233,a 0,2 = 2333,a 0,3 = 23333…) Besides, in 233 matrix, we got a i,j = a i-1,j +a i,j-1( i,j ≠ 0). Now you have known a 1,0,a 2,0,…,a n,0, could you tell me a n,m in the 233 matrix?
Input
There are multiple test cases. Please process till EOF.

For each case, the first line contains two postive integers n,m(n ≤ 10,m ≤ 10 9). The second line contains n integers, a 1,0,a 2,0,…,a n,0(0 ≤ a i,0 < 2 31).
Output
For each case, output a n,m mod 10000007.
Sample Input
1 1
1
2 2
0 0
3 7
23 47 16
Sample Output
234
2799
72937
233 Matrix HDU - 5015(矩阵快速幂)
解题思路:由题意可得矩阵的第一列
0
a[1]

a[2]

a[3]

a[4]

为了凑233转化为

23

a[1]

a[2]

a[3]

a[4]

3

由 a i,j = a i-1,j +a i,j-1可以得到第二列

23*10+3

a[1]+23*10+3

a[2]+a[1]+23*10+3

a[3]+a[2]+a[1]+23*10+3

a[4]+a[3]+a[2]+a[1]+23*10+3

3

由此推得转移矩阵

10 0 0 0 0 1

10 1 0 0 0 1

10 1 1 0 0 1

10 1 1 1 0 1

10 1 1 1 1 1

0 0 0 0 0 1
233 Matrix HDU - 5015(矩阵快速幂)
如图将每一列的都求出来,到最后一列就是转移方程的m次方
那么最后一列就是A的m次方乘第一列。在求转移矩阵的时候使用快速幂的思想,最后求出来的结果是一个矩阵。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 15
const int mod=10000007;//因为数很大需要取模
int n;
int b[N];
struct Mat
{
    long long mat[N][N];
}a,ans;
Mat mul(Mat a,Mat b)
{
    int i,j,k;
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    for(i=0; i<=n+1; i++)
    {
        for(j=0; j<=n+1; j++)
        {
            c.mat[i][j]=0;
            for(k=0; k<=n+1; k++)
            {
                if(a.mat[i][k]&&b.mat[k][j])
                {
                    c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];//矩阵乘法
                    c.mat[i][j]%=mod;
                }
            }
        }
    }
    return c;//返回乘完了之后的矩阵
}
void kuaisumi(int m)
{
    int i;
    memset(ans.mat,0,sizeof(ans.mat));
    for(i=0;i<=n+1;i++)
        ans.mat[i][i]=1;
    while(m)//使用快速幂的思想进行矩阵的m次方相乘
    {
        if(m&1)//就是m%2==0
            ans=mul(ans,a);
        m/=2;
        a=mul(a,a);
    }
}
void inti()
{
    int i,j;
    b[0]=23;//b数组就是第一列,最后与转移矩阵的m次方相乘得到anm
    b[n+1]=3;
    for(i=1; i<=n; i++)
        scanf("%d",&b[i]);
    memset(a.mat,0,sizeof(a.mat));
    for(i=0; i<=n; i++)
    {
        a.mat[i][0]=10;
        a.mat[i][n+1]=1;
    }
    a.mat[n+1][n+1]=1;
    for(i=1; i<n+1; i++)
    {
        for(j=1; j<=i; j++)
        {
            a.mat[i][j]=1;
        }
    }
}
int main()
{
    int i,m;
    while(~scanf("%d%d",&n,&m))
    {
        inti();
        kuaisumi(m);
        long long s=0;
        for(i=0;i<=n+1;i++)
            s=(s+(ans.mat[n][i]*b[i])%mod)%mod;
        printf("%lld\n",s);
    }
    return 0;
}
相关标签: 矩阵