Description
每组输出一行为 Case 组号: 答案,即M时刻活着的小宠物个数%10000
根据题意建立这样一种数列 根据题意建立这样一种数列 根据题意建立这样一种数列 根据题意建立这样一种数列 根据题意建立这样一种数列 ,数列从 0号开始 号开始 .. 代表第 0个单 位时间出生的小宠物 位时间出生的小宠物 位时间出生的小宠物 位时间出生的小宠物 ...1 代表在第 1个单位时间出生的小宠物 个单位时间出生的小宠物 个单位时间出生的小宠物 个单位时间出生的小宠物 .. 以 此类推 .. 将这个数列某项称作 将这个数列某项称作 将这个数列某项称作 Z[x]
显然 .. 当 x>=5 时.. 在第 x天活着的小宠物数量 天活着的小宠物数量 天活着的小宠物数量 sum[x] = sum[x] = sum[x] = sum[x] = sum[x] = z[x -5] + z[x -4] + z[x -3] +z[x -2] +z[x -1] + z[x]
再看根据题意 再看根据题意 再看根据题意 再看根据题意 再看根据题意 再看根据题意 z[x] = x z[x] = x z[x] = xz[x] = z[x z[x] = x z[x] = x-2]/2*6 + z[x 2]/2*6 + z[x 2]/2*6 + z[x 2]/2*6 + z[x2]/2*6 + z[x 2]/2*6 + z[x 2]/2*6 + z[x-3]/2*4 + 3]/2*4 + 3]/2*4 + 3]/2*4 + 3]/2*4 + 3]/2*4 + z[x -4]/2*2 = z[x -2]*3 + z[x -3]*2 + z[x -4]
显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公显然这个式 子是一递推的公... 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 那么就可以用矩阵乘法来 求解这个递推公式的第 解这个递推公式的第 解这个递推公式的第 解这个递推公式的第 x项是多少 ... 观察数 列建立关于这个递推观察数 列建立关于这个递推观察数 列建立关于这个递推观察数 列建立关于这个递推观察数 列建立关于这个递推列的 "特征 “矩阵 ..
M = 0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
0 0 1 2 3 0
而初始值为 0单位时间的出生情况 单位时间的出生情况 单位时间的出生情况 单位时间的出生情况 ... 可以自己递推出来 可以自己递推出来 可以自己递推出来 ... 为 A = { 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 }
要求第 x天出生了多少就用 天出生了多少就用 天出生了多少就用 z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)...z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... 矩阵乘法用 递归 2分来求解 分来求解 ... ...
要 求 sum(x)... 就分别求
出 z[x -5] ,z[x 5] ,z[x5] ,z[x 5] ,z[x -4] ,z[x 4] ,z[x4] ,z[x 4] ,z[x -3] ,z[x 3] ,z[x3] ,z[x 3] ,z[x -2] ,z[x 2] ,z[x2] ,z[x 2] ,z[x -1] ,z[x] 1] ,z[x]1] ,z[x] 1] ,z[x] 1] ,z[x]再将 这几个值加起来就行了 这几个值加起来就行了 这几个值加起来就行了 这几个值加起来就行了 ....
Code:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #define LL long long using namespace std; const int N = 52; static int mod = 1111; struct Matrix { int mat[N][N]; //修改long long or int int n, m; Matrix() {//初始化,根据需要可以把此处删除! n = m = N; memset(mat, 0, sizeof(mat)); } inline void init(int row, int column) {//初始矩阵大小 n = row, m = column; } void init_e() {//初始化为单位矩阵 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { mat[i][j] = (i == j); } } } void print() {//测试检查用 puts("——————————————"); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { printf("%d ", (int)mat[i][j]); }puts(""); }puts(""); } }; //加法 重载运算符 + Matrix operator + (Matrix a, Matrix b) { Matrix ret; ret.init(a.n, a.m); for (int i = 0; i < a.n; i++) { for (int j = 0; j < a.m; j++) { ret.mat[i][j] = a.mat[i][j] + b.mat[i][j]; if (ret.mat[i][j] >= mod) { //这里的mod,没必要时要删除 ret.mat[i][j] %= mod; } } } return ret; }//加法 //n行m列 * m行p列 = n行p列 重载运算符 * Matrix operator * (Matrix a, Matrix b) { Matrix ret; ret.init(a.n, b.m); for (int i = 0; i < a.n; i++) { for (int k = 0; k < a.m; k++) if (a.mat[i][k]) { for (int j = 0; j < b.m; j++) if (b.mat[k][j]) { ret.mat[i][j] = ret.mat[i][j] + a.mat[i][k] * b.mat[k][j]; if (ret.mat[i][j] >= mod) { ret.mat[i][j] %= mod; }//if }//for(j) }//for(k) }//for(i) return ret; }//乘法 //求幂一般都是正方形矩阵,所以ret = a; 重载运算符 ^ Matrix operator ^ (Matrix a, int b) { Matrix ret = a, tmp = a; ret.init_e(); for ( ; b; b >>= 1) { if (b & 1) { ret = ret * tmp; } tmp = tmp * tmp; } return ret; }// //递归幂求和 //用二分法求矩阵和,递归实现,一般用下一种非递归版 Matrix Power_Sum1(Matrix a, int b) { Matrix ret = a; ret.init_e(); if (b == 1) { return a; } else if (b & 1) { return (a ^ b) + Power_Sum1(a, b - 1); } else { return Power_Sum1(a, b >> 1) * ((a ^ (b >> 1)) + ret); } }//Power_Sum1 //非递归幂求和 Matrix Power_Sum2(Matrix a, int b) { int k = 0 ,ss[32]; Matrix tp1, tp2, ret; tp1 = tp2 = ret = a; ret.init_e(); while (b) { ss[k++] = b & 1; b >>= 1; } for (int i = k - 2; i >= 0; i--) { tp1 = tp1 * (tp2 + ret); tp2 = tp2 * tp2; if (ss[i]) { tp2 = tp2 * a; tp1 = tp1 + tp2; } } return tp1; }//Power_Sum2 int main() { mod=10000; int M,cas=1; Matrix t0; t0.init(6,1); t0.mat[0][0]=2; for(int i=1;i<6;i++) t0.mat[i][0]=0; while(scanf("%d",&M)==1) { Matrix t; t.init(6,6); t.mat[0][0]=t.mat[0][4]=t.mat[0][5]=0; t.mat[0][1]=3; t.mat[0][2]=2; t.mat[0][3]=1; for(int i=1;i<6;i++) { for(int j=0;j<6;j++) t.mat[i][j]=(j==(i-1)); } //t.print(); if(M==0) { printf("Case %d: %d\n",cas++,(2%mod)); continue; } t=t^M; Matrix ans=t0; ans=t*ans; LL sum=0; for(int i=0;i<6;i++) sum=(sum+ans.mat[i][0])%mod; printf("Case %d: %lld\n",cas++,sum); } return 0; } /************************************************************** Problem: 1313 User: Roney Language: C++ Result: Accepted Time:400 ms Memory:1484 kb ****************************************************************/