BZOJ 5336: [TJOI2018] party Dp Dp sleeve

title

\(~\)
BZOJ 5336
LUOGU 4590
Description

Adzuki bean participated in the NOI's garden party, a meeting room, each completed project will get a medal, medals will only be N, O, I, the words. In the meeting room, he collected a string consisting of K medal.
Awarding rule is the longest common subsequence length of the string and awarding medals as the last string of adzuki reward level.
Awarding now known string length is N, and does not appear in the awarding medal three consecutive string of NOI, i.e. does not appear in the medal substring NOI.
Adzuki bean now want to know how many different legal awarding bonus level will correspond to each string.

Input

The first two row number, N, K string representing the length of cashing, adzuki collected medals length of the string.
The second line of a total of K characters indicating adzuki string obtained medals.
N <= 1000 & K <= 15

Output

A total of K + 1 line, the i-th row is represented by adzuki final bonus level i-1 the number of different strings of legitimate Duijiang, this number will be significant, the results of 10 ^ 7 + 9 mod.

Sample Input

3 2
NO

Sample Output

. 1
19
. 6
prompt
string length of the longest common subsequence 0 are: III;
string of the longest common subsequence lengths are 2: NON, NNO, NOO, ONO , INO, NIO;
removed NOI, the remaining 19 (26-6 -1) kinds of the longest common subsequence length of 1.

analysis

And discovered that in fact the questions BZOJ 3864 as just one more layer of restrictions, can not appear \ (NOI \) character, then we set up a multi-state one-dimensional recording the first two thousand million.

Specific look at the code can learn from him.

code

#include<bits/stdc++.h>
using namespace std;
const int maxk=16,mod=1e9+7;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

template<typename T>inline void write(T x)
{
    if (!x) { putchar('0'); return ; }
    if (x<0) putchar('-'), x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) putchar(ch[num--]);
}

typedef int iarr[maxk+1];
iarr a,f,g,ans;
int v[1<<maxk][3],w[3][3];
int F[2][1<<maxk][3];
char ch[maxk+1];
int main()
{
    int n,m;read(n);read(m);
    scanf("%s",ch+1);
    for (int i=1; i<=m; ++i)
    {
        if (ch[i]=='N') a[i]=0;
        if (ch[i]=='O') a[i]=1;
        if (ch[i]=='I') a[i]=2;
    }
    for (int i=0; i<(1<<m); ++i)
    {
        for (int j=0; j<m; ++j) f[j+1]=f[j]+(i>>j&1);
        for (int j=0; j<3; ++j)
        {
            for (int k=1; k<=m; ++k)
                if (a[k]==j) g[k]=f[k-1]+1;
                else g[k]=max(f[k],g[k-1]);
            v[i][j]=0;
            for (int k=1; k<=m; ++k)
                if (g[k]>g[k-1]) v[i][j]|=1<<(k-1);
        }
    }
    w[0][0]=1,w[0][1]=0,w[0][2]=0;
    w[1][0]=1,w[1][1]=2,w[1][2]=0;
    w[2][0]=1,w[2][1]=0,w[2][2]=3;
    for (int j=0; j<(1<<m); ++j)
        for (int l=0; l<3; ++l) F[0][j][l]=0;
    int x=0;F[0][0][0]=1;
    for (int i=0; i<n; ++i,x^=1)
    {
        for (int j=0; j<(1<<m); ++j)
            for (int l=0; l<3; ++l) F[x^1][j][l]=0;//memset(F[x^1],0,sizeof(F[x^1]));
        for (int j=0; j<(1<<m); ++j)
            for (int l=0; l<3; ++l) if (F[x][j][l])
                for (int k=0; k<3; ++k)
                    if (w[l][k]<3) F[x^1][v[j][k]][w[l][k]]=(F[x^1][v[j][k]][w[l][k]]+F[x][j][l])%mod;
    }
    for (int i=0,v; i<(1<<m); ++i)
    {
        v=__builtin_popcount(i);
        for (int l=0; l<3; ++l) ans[v]=((long long)ans[v]+F[x][i][l])%mod;
    }
    for (int i=0; i<=m; ++i) write(ans[i]),puts("");
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11318560.html
DP