首页 > 代码库 > BZOJ 4416 阶乘字符串

BZOJ 4416 阶乘字符串

状压dp。状态有点难想,方程十分简单。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 455using namespace std;int t,n,g[maxn][23],f[(1<<22)+5],len,regis[23];char s[maxn];void work(){    memset(g,0,sizeof(g));    memset(f,0,sizeof(f));    scanf("%d",&n);    scanf("%s",s);    if (n>21) {printf("NO\n");return;}    len=strlen(s);    for (register int i=1;i<=21;i++) regis[i]=len+1;    for (register int i=len-1;i>=0;i--)    {        for (register int j=1;j<=n;j++)            g[i+1][j]=regis[j];        regis[s[i]-a+1]=i+1;    }    for (register int i=1;i<=n;i++) g[0][i]=regis[i];    for (register int i=1;i<=n;i++) g[len][i]=g[len+1][i]=len+1;    int top=(1<<n)-1;    for (register int i=0;i<=top;i++)        for (register int j=1;j<=n;j++)            if (i&(1<<(j-1)))                f[i]=max(f[i],g[f[i^(1<<(j-1))]][j]);    if (f[top]==len+1) printf("NO\n");    else printf("YES\n");}int main(){    scanf("%d",&t);    for (int i=1;i<=t;i++)        work();    return 0;}

 

BZOJ 4416 阶乘字符串