202006-4 1246
思路:
这道题一开始还是暴力,得了32分。讲真的也是通过这道题了解到了矩阵快速幂这个算法,感觉在dp算法中非常好用,感谢CSP。
这里我只考虑S = 2的情况,看上一步有哪一个数能够到这一步来,然后每一次迭代就可以了,这就是递推,也是矩阵快速幂的用处。
代码:
#include#include #include #include using namespace std; const int N = 14; const int mod = 998244353; typedef long long ll; vector<int> ver = {1, 2, 4, 6, 16, 26, 41, 42, 44, 46, 61, 62, 64, 66}; int idx[100];//离散化 vector int>> g = { {2}, {4}, {1,6,16}, {6,4,64}, {26}, {46}, {62}, {64}, {61}, {66}, {42}, {44}, {41}, {46} }; int tr[N][N];//转移矩阵 int n; string s; void init(){ memset(idx, -1, sizeof(idx));//初始化 for(int i = 0;i ){ // int num = ver[i]; idx[ver[i]] = i;//离散化 } //得到转移矩阵 for(int i = 0;i ){ for(auto t:g[i]){ int num = t; int b = idx[t]; tr[idx[t]][i]++;//如果t可以由i转过来,那么第n次的t的个数由第n - 1次的i的个数决定 } } } int res[N][N]; void mul(int c[][N], int a[][N], int b[][N]){ int tmp[N][N]; memset(tmp, 0, sizeof(tmp)); for(int i = 0;i ){ for(int j = 0;j ){ for(int k = 0;k ){ tmp[i][j] = (tmp[i][j] + (ll)a[i][k] * b[k][j])%mod; } } } memcpy(c, tmp, sizeof(tmp)); } int qmi(int k, int id){ int w[N][N]; memcpy(w, tr, sizeof(w)); res[0][0] = 1; while(k){ if(k & 1)mul(res, w, res); mul(w,w,w); k>>=1; } return res[idx[id]][0]; } int main(){ cin>>n; cin>>s; init(); cout< endl; }