给定一个由前n个小写字母组成的串S。
串S是阶乘字符串当且仅当前n个小写字母的全排列(共n!种)都作为S的子序列(可以不连续)出现。
由这个定义出发,可以得到一个简单的枚举法去验证,但是它实在太慢了。所以现在请你设计一个算法,在1秒内判断出给定的串是否是阶乘字符串。
标签:
#include<cstdio> #include<cctype> #include<queue> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; return x*f; } const int maxn=510; const int maxm=1<<22; int n,m,f[maxm],g[maxn][23]; char s[maxn]; void solve() { n=read();scanf("%s",s+1);m=strlen(s+1); if(n>21) {puts("NO");return;} dwn(i,m+1,0) { rep(j,0,n-1) g[i][j]=(i>=m?m+1:g[i+1][j]); if(i!=m) g[i][s[i+1]-‘a‘]=i; } rep(S,1,(1<<n)-1) { int c=0; rep(i,0,n-1) if(S>>i&1) c=max(c,g[f[S^(1<<i)]][i]); f[S]=c; } puts(f[(1<<n)-1]<=m?"YES":"NO"); } int main() { dwn(T,read(),1) solve(); return 0; }
标签:
原文地址:http://www.cnblogs.com/wzj-is-a-juruo/p/5259295.html