蒜头君的兔子(计蒜客)

                                                                蒜头君的兔子

题意:有个姓蒜的第一年有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!


猜你喜欢

转载自blog.csdn.net/qq_38944163/article/details/80724109
今日推荐