蒜头君的兔子(计蒜客)
题意:有个姓蒜的第一年有1对兔子,兔子到第二年之后每年会生一对兔子,到十岁的时候就会gg,为n年后有几只兔子。
我一开始是直接维护了一个0~10的数组,分别表示0~10岁的兔子分别有多少个,每次暴力转移。
代码:
#include<bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
long long s,n,a[1000005];
int main(){
cin>>n;
a[0]=1;
for(int i=1;i<=n;i++){
s=0;
for(int j=10;j>=1;j--){
a[j]=a[j-1];
}
for(int j=10;j>1;j--) s=(s+a[j])%mod;
a[0]=s;
}
s=0;
for(int i=0;i<10;i++) s=(s+a[i])%mod;
cout<<s%mod;
return 0;
}
然而好像超时了。
那么我们想想怎么优化,嗯没错,我们伟大的矩阵快速幂。
为此,我手写了一个11*11的矩阵(因为0~10共有11个数)。
跑起来飞快。
代码:
#include<bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
struct matrix {
long long a[105][105];
};
matrix matrix_mul(matrix A, matrix B) {
// 2 个矩阵相乘
matrix C;
for (int i = 0; i <= 10; ++i) {
for (int j = 0; j <= 10; ++j) {
C.a[i][j] = 0;
for (int k = 0; k <= 10; ++k) {
C.a[i][j]=(C.a[i][j]+A.a[i][k] * B.a[k][j]%mod)%mod ;
}
}
}
return C;
}
matrix unit() {
// 返回一个单位矩阵
matrix res;
for (int i = 0; i <= 10; ++i) {
for (int j = 0; j <= 10; ++j) {
if (i == j) {
res.a[i][j] = 1;
} else {
res.a[i][j] = 0;
}
}
}
return res;
}
matrix matrix_pow(matrix A, int n) {
matrix res = unit(), temp = A;
for (; n; n /= 2) {
if (n & 1) {
res = matrix_mul(res, temp);
}
temp = matrix_mul(temp, temp);
}
return res;
}
int x,y,k,n,m;
int main()
{
scanf("%d",&n);
matrix a; //开始以为能直接赋值,发现gg了。
// a.a[0]={0,0,1,1,1,1,1,1,1,1,1};
// a.a[1]={1,0,0,0,0,0,0,0,0,0,0};
// a.a[2]={0,1,0,0,0,0,0,0,0,0,0};
// a.a[3]={0,0,1,0,0,0,0,0,0,0,0};
// a.a[4]={0,0,0,1,0,0,0,0,0,0,0};
// a.a[5]={0,0,0,0,1,0,0,0,0,0,0};
// a.a[6]={0,0,0,0,0,1,0,0,0,0,0};
// a.a[7]={0,0,0,0,0,0,1,0,0,0,0};
// a.a[8]={0,0,0,0,0,0,0,1,0,0,0};
// a.a[9]={0,0,0,0,0,0,0,0,1,0,0};
// a.a[10]={1,0,0,0,0,0,0,0,0,1,0};//纯手打矩阵……快疯掉了,好在没出现细节错误,不然会调到屎的。
a.a[0][0]=0;a.a[0][1]=1;a.a[0][2]=1;a.a[0][3]=1;a.a[0][4]=1;a.a[0][5]=1;a.a[0][6]=1;a.a[0][7]=1;a.a[0][8]=1;a.a[0][9]=1;a.a[0][10]=0;
a.a[1][0]=1;a.a[1][1]=0;a.a[1][2]=0;a.a[1][3]=0;a.a[1][4]=0;a.a[1][5]=0;a.a[1][6]=0;a.a[1][7]=0;a.a[1][8]=0;a.a[1][9]=0;a.a[1][10]=0;
a.a[2][0]=0;a.a[2][1]=1;a.a[2][2]=0;a.a[2][3]=0;a.a[2][4]=0;a.a[2][5]=0;a.a[2][6]=0;a.a[2][7]=0;a.a[2][8]=0;a.a[2][9]=0;a.a[2][10]=0;
a.a[3][0]=0;a.a[3][1]=0;a.a[3][2]=1;a.a[3][3]=0;a.a[3][4]=0;a.a[3][5]=0;a.a[3][6]=0;a.a[3][7]=0;a.a[3][8]=0;a.a[3][9]=0;a.a[3][10]=0;
a.a[4][0]=0;a.a[4][1]=0;a.a[4][2]=0;a.a[4][3]=1;a.a[4][4]=0;a.a[4][5]=0;a.a[4][6]=0;a.a[4][7]=0;a.a[4][8]=0;a.a[4][9]=0;a.a[4][10]=0;
a.a[5][0]=0;a.a[5][1]=0;a.a[5][2]=0;a.a[5][3]=0;a.a[5][4]=1;a.a[5][5]=0;a.a[5][6]=0;a.a[5][7]=0;a.a[5][8]=0;a.a[5][9]=0;a.a[5][10]=0;
a.a[6][0]=0;a.a[6][1]=0;a.a[6][2]=0;a.a[6][3]=0;a.a[6][4]=0;a.a[6][5]=1;a.a[6][6]=0;a.a[6][7]=0;a.a[6][8]=0;a.a[6][9]=0;a.a[6][10]=0;
a.a[7][0]=0;a.a[7][1]=0;a.a[7][2]=0;a.a[7][3]=0;a.a[7][4]=0;a.a[7][5]=0;a.a[7][6]=1;a.a[7][7]=0;a.a[7][8]=0;a.a[7][9]=0;a.a[7][10]=0;
a.a[8][0]=0;a.a[8][1]=0;a.a[8][2]=0;a.a[8][3]=0;a.a[8][4]=0;a.a[8][5]=0;a.a[8][6]=0;a.a[8][7]=1;a.a[8][8]=0;a.a[8][9]=0;a.a[8][10]=0;
a.a[9][0]=0;a.a[9][1]=0;a.a[9][2]=0;a.a[9][3]=0;a.a[9][4]=0;a.a[9][5]=0;a.a[9][6]=0;a.a[9][7]=0;a.a[9][8]=1;a.a[9][9]=0;a.a[9][10]=0;
a.a[10][0]=0;a.a[10][1]=0;a.a[10][2]=0;a.a[10][3]=0;a.a[10][4]=0;a.a[10][5]=0;a.a[10][6]=0;a.a[10][7]=0;a.a[10][8]=0;a.a[10][9]=1;a.a[10][10]=0;
a=matrix_pow(a,n-1);
long long ans=0;
for(int i=0;i<10;i++) ans=(ans+a.a[i][1])%mod;
printf("%d",ans);
return 0;
}
perfect!