Description
Input
Output
每組輸出一行爲 Case 組號: 答案,即M時刻活着的小寵物個數%10000
Sample Input
Sample Output
根據題意建立這樣一種數列 根據題意建立這樣一種數列 根據題意建立這樣一種數列 根據題意建立這樣一種數列 根據題意建立這樣一種數列 ,數列從 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
****************************************************************/