meaning of the title
Sol
This question may be the only non template question of TJOI2018..
Considering the transfer equation of LCS,
\[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1] + (A_i = B_j))\]
That is to say, I f we know the previous column vector \ (f[i - 1] \) and \ (A_i, B_j \), we can transfer it
Then dp can be used violently, \ (f[i][sta][0/1/2] \) indicates to position \ (I \). The current LCS array is the scheme number of STA, but the status is obviously \ (K^K \). A property has been observed: each position in sta is at most \ (1 \) different from the previous position. In fact, only one differential array needs to be recorded. The state transferred to can be preprocessed.
Complexity \ (O(9 * N * 2^K) \)
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 10, mod = 1e9 + 7; template <typename A, typename B> inline int add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;} template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);} inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, K; int f[2][(1 << 15) + 1][3], trans[(1 << 15) + 1][3], one[(1 << 15) + 1], ans[16]; char s[MAXN], ss[5] = "NOI"; int Get(int sta, int c) { int pre[16] = {}, nw[16] = {}; for(int i = 1; i <= K; i++) pre[i] = pre[i - 1] + ((sta >> (i - 1)) & 1); for(int i = 1; i <= K; i++) { if(ss[c] == s[i]) nw[i] = pre[i - 1] + 1; else nw[i] = max(nw[i - 1], pre[i]); } int ans = 0; for(int i = 1; i <= K; i++) ans += (nw[i] - nw[i - 1]) << (i - 1); return ans; } signed main() { N = read(); K = read(); scanf("%s", s + 1); f[0][0][0] = 1; int lim = 1 << K; for(int sta = 0; sta < lim; sta++) { one[sta] = one[sta >> 1] + (sta & 1); for(int i = 0; i < 3; i++) trans[sta][i] = Get(sta, i); } int o = 0; for(int i = 0; i <= N; i++) { memset(f[o ^ 1], 0, sizeof(f[o ^ 1])); for(int sta = 0; sta < lim; sta++) { for(int len = 0; len < 3; len++) { for(int c = 0; c < 3; c++) { int nxt; if(c == 0) nxt = 1; else if(c == 1) nxt = (len == 1 ? 2 : 0); else if(c == 2) nxt = (len == 2 ? 3 : 0); if(nxt == 3) continue; add2(f[o ^ 1][trans[sta][c]][nxt], f[o][sta][len]); } // cout << f[i + 1][sta][len] << '\n'; } } o ^= 1; } for(int i = 0; i < lim; i++) for(int j = 0; j < 3; j++) add2(ans[one[i]], f[o ^ 1][i][j]); for(int i = 0; i <= K; i++) cout << ans[i] << '\n'; return 0; } /* */