# bzoj5336:[TJOI2018]party

### 传送门

dp套dp的板子题

$dp[i][j]=max{dp[i-1][j],dp[i][j-1],dp[i-1}[j-1]+(a[i]==b[i])$

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
{
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
#define rg register
const int mod=1e9+7;
int ans[20],n,k,f[2][1<<15][3],a[1<<15],b[1<<15],s[1<<15][3],m;
char ch[20],d[3]={'N','O','I'};
int prepare(int s,int w){
memset(b,0,sizeof b);
for(rg int i=1;i<=k;i++)a[i]=a[i-1]+((s>>(i-1))&1);
for(rg int i=1;i<=k;i++){
if(d[w]==ch[i])b[i]=a[i-1]+1;
else b[i]=max(a[i],b[i-1]);
}
int ans=0;
for(rg int i=1;i<=k;i++)ans|=(b[i]-b[i-1])<<(i-1);
return ans;
}
int get_size(int x){int ans=0;while(x)ans+=x&1,x>>=1;return ans;}
signed main(){
for(rg int i=0;i<m;i++)
for(rg int j=0;j<3;j++)
s[i][j]=prepare(i,j);
f[0][0][0]=1;int x=0,y=1;
for(rg int i=1;i<=n;i++){
swap(x,y);memset(f[x],0,sizeof f[x]);
for(rg int j=0;j<m;j++)
for(rg int las=0;las<3;las++)
for(rg int now=0;now<3;now++){
int g=!now?1:(now==1)?(las==1?2:0):(las==2?3:0);
if(g==3)continue;