1.题目描述:
2.题意概述:
有一个矩阵横排第一行初始是0,233,2333,23333...,然后给出计算公式a[i][j] = a[i - 1][j] + a[i][j - 1],然后给出了n和m和第一列的各值要求计算a[n][m]的值。
3.解题思路:
因为a[0][1]=233,a[0][2]=2333,a[0][3]=23333,…………,所以有a[0][i]=10*a[0][i-1]+3(i>1,a[0][1]=233)
如果令a[0][0]=23,那么a[0][i]=10*a[0][i-1]+3(i>0,a[0][0]=23)
则对于n+1行,m+1列的矩阵A,有
第一列(下标j=0)
第二列(下标j=1)
第三列(下标j=2)
对上述矩阵的各列适当变形得:
第一列(下标j=0)
第二列(下标j=1)
第三列(下标j=2)
所以有
根据上面的递推公式,我们可以构造矩阵得,
4.AC代码:
#include
#include
#include
using namespace std;
struct matrix
{
__int64 mat[15][15];
matrix()
{
memset(mat, 0, sizeof(mat));
}
};
int n;
const int mod = 10000007;
matrix mul(matrix B, matrix A) //左乘列矩阵
{
int i, j, k;
matrix C;
for (i = 1; i <= n + 2; i++)
for (j = 1; j <= n + 2; j++)
for (k = 1; k <= n + 2; k++)
C.mat[i][j] = (C.mat[i][j] + B.mat[i][k] * A.mat[k][j]) % mod;
return C;
}
matrix powmul(matrix A, int m)
{
matrix ans;
for (int i = 1; i <= n + 2; i++)
ans.mat[i][i] = 1; //单位矩阵
while (m > 0)
{
if (m & 1)
ans = mul(ans, A);
A = mul(A, A);
m >>= 1;
}
return ans;
}
int main()
{
//freopen("input.txt", "r", stdin);
int m;
while (scanf("%d%d", &n, &m) != EOF)
{
matrix A, B;
A.mat[1][1] = 23; //原矩阵首元素为23,使每一列都可以被转换(原来第二列不行
for (int i = 1; i <= n; i++)
scanf("%d", &A.mat[i + 1][1]);
A.mat[n + 2][1] = 3;
for (int i = 1; i <= n + 1; i++)
B.mat[i][1] = 10;
for (int i = 1; i <= n + 2; i++)
B.mat[i][n + 2] = 1;
for (int i = 1; i < n + 2; i++)
for (int j = 2; j <= i; j++)
B.mat[i][j] = 1; //转移矩阵的下三角单位阵
B = powmul(B, m);
A = mul(B, A); //A除了第一列之外所有的元素都是0,相当于列矩阵
cout << A.mat[n + 1][1] << endl;
}
return 0;
}