JZOJ 3293. 阶乘字符串
题目
分析
- 设f[s]为满足阶乘字符串的集合的最后一个字母的位置
-
g[i][j]表示以i+1开始的第一个j字母出现的位置。
然后枚举子集转移,最后判断一下是否满足f[(1<<n)−1]≤m 即可,本题解决。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 int g[1001][1001]; 7 int f[10000001]; 8 string s; 9 int n; 10 int main () 11 { 12 int T; 13 cin>>T; 14 while(T) 15 { 16 T--; 17 cin>>n; 18 cin>>s; 19 int m=1<<n; 20 int len=s.size(); 21 if (n>21) 22 { 23 cout<<"NO"<<endl; 24 continue; 25 } 26 for (int i=0;i<n;i++) g[len][i]=g[len+1][i]=len+1; 27 for (int i=len;i;i--) 28 { 29 for (int j=0;j<n;j++) g[i-1][j]=g[i][j]; 30 g[i-1][s[i-1]-'a']=i; 31 } 32 memset(f,0,sizeof(f)); 33 for (int i=1;i<m;i++) 34 { 35 for (int j=0;j<n;j++) 36 { 37 if (i&(1<<j)) f[i]=max(f[i],g[f[i^(1<<j)]][j]); 38 } 39 } 40 if (f[m-1]<=len) cout<<"YES"<<endl; 41 else cout<<"NO"<<endl; 42 } 43 }
为何要逼自己长大,去闯不该闯的荒唐