Description
Gene cluster is ACGT4 letters, we have a sequence of length n, S. Gene Wants to know the length of a gene string m, the longest common subsequence S are 0; 1;; each of several strings of n.
The remainder output answers to 10 ^ 9 + 7.
Input
The first line of a string S. The second line a positive integer m.
Output
row n + 1, i + 1 th row common subsequence S represents the remainder of a few about 10 ^ 7 + 9 i of the string.
Sample Input
GTC
10
Sample Output
1
22783
528340
497452
Data Constraint
10% of the data n <= 3; m <= 10.
50% of the data n <= 6; m <= 100.
100% data n <= 10; m <= 1000.
Thinking
We can consider the request for the longest common subsequence of two strings dp: f [i, j] represents the first sequence to i, the second string to the longest common subsequence j. For two strings, if the array f [i] is exactly the same, they impact on the back is exactly the same, so we can set two-dimensionally: F [i, j], and to represent our current i, f [i] state j is a number of programs, but set so that the state of the second dimension is 10 10 . We found a f [i, j] will not [i, j-1] is smaller than F, and a maximum ratio of f [i, j-1] over, so we can take a reset state when the difference, it becomes 2 10 .
Code
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1050,Mo = 1000000007;
char s[12];
int f[MAXN][MAXN],s1[12],F[12],Nt[12],No[12],N,M;
int max(int a,int b) {return a > b ? a : b;}
int main()
{
scanf("%s",s);
N = strlen(s);
for(int i = 0;i < N;i ++)
if (s[i] == 'A') s1[i + 1] = 1; else if (s[i] == 'C') s1[i + 1] = 2; else
if (s[i] == 'G') s1[i + 1] = 3; else s1[i + 1] = 4;
scanf("%d", &M);
f[0][0] = 1;
for(int i = 0;i < M;i ++)
for(int j = 0;j < (1 << N);j ++)
if (f[i][j])
for(int z = 1;z <= 4;z ++)
{
for(int k = 1;k <= N;k ++) Nt[k] = 0;
for(int tmp = j,k = 0;tmp;tmp /= 2) Nt[N - (++ k) + 1] = tmp % 2;
for(int p = 1;p <= N;p ++) Nt[p] += Nt[p - 1];
int tmp = 0;
for(int k = 1;k <= N;k ++)
{
No[k] = max(No[k - 1],Nt[k]);
if (z == s1[k]) No[k] = max(No[k],Nt[k - 1] + 1);
tmp = tmp * 2 + (No[k] - No[k - 1]);
}
f[i + 1][tmp] = (f[i + 1][tmp] + f[i][j]) % Mo;
}
for(int i = 0;i < (1 << N);i ++)
{
int c = 0;for(int tmp = i;tmp;tmp /= 2) c += tmp % 2;
F[c] = (F[c] + f[M][i]) % Mo;
}
for(int i = 0;i <= N;i ++) printf("%d\n",F[i]);
}