版权声明:_ https://blog.csdn.net/lunch__/article/details/83893120
题意
- 给你一个8个点的环,每次可以走一步到一个相邻的点上,求 号点到 号点走 步的方案数,
一开始题目看错了…
首先设 为 走到 走了 步的方案数
那么
这种线性递推的转移可以用矩阵优化
令矩阵元素定义为 到 的方案数
那么直接用快速幂转移
转移的过程实际就是上面那个递推式的过程
复杂度
Codes
#include <bits/stdc++.h>
#define For(i, a, b) for (register int i = (a), i##_end = (b); i <= i##_end; ++ i)
#define FOR(i, a, b) for (register int i = (a), i##_end = (b); i <= i##_end; ++ i)
using namespace std;
const int mod = 1e3;
const int N = 9;
struct Martix {
int a[N][N];
Martix(int opt = 0) {
memset(a, 0, sizeof(a));
if (opt == 1) For(i, 1, 8)
a[i][i] = 1;
if (opt == 2) {
For(i, 1, 7) a[i][i + 1] = 1, a[i + 1][i] = 1;
a[8][1] = a[1][8] = (a[5][4] = a[5][6] = 0) ^ 1;
}
}
Martix operator * (const Martix &T) const {
Martix ans;
For(i, 1, 8) For(j, 1, 8) For(k, 1, 8)
(ans.a[i][j] += a[i][k] * T.a[k][j]) %= mod;
return ans;
}
};
Martix qpow(Martix a, int x) {
Martix ret(1);
while (x) {
if (x & 1) ret = ret * a;
x >>= 1, a = a * a;
}
return ret;
}
int main() {
#ifdef ylsakioi
freopen("2233.in", "r", stdin);
freopen("2233.out", "w", stdout);
#endif
int n; cin >> n;
printf("%d\n", qpow(Martix(2), n).a[1][5]);
return 0;
}