这个 \(n\le 22\) 的数据范围一看就是那种正解 \(O(n2^n)\) 不知道为啥还去卡 \(O(n^22^n)\) 的玩意儿吧,结合题面大致就能猜到它是个状压DP状物。
然后应该普遍就能想到是把每个字符当前在不在串里压成状态,按每一步加一个或者是删一个字符转移状态。
限制是有一步形成的字符串不一样才算不同方案,所以这样做会产生一个问题就是在相同字符组成的连续段中删(或加)不同的字符是等效的,这个时候我们只算连续段末尾的字符的贡献来去重。
注意到如果从空串开始去重会比较麻烦,所以我选择的是从满串倒着删,按剩下字符的数量从多到少做就完了,感觉没啥难点。
#include<bits/stdc++.h>
#define mod 998244353
#define int long long
using namespace std;
char x[30];
int dp[1<<22];
signed main(){int n;scanf("%lld",&n);scanf("%s",x+1);dp[(1<<n)-1]=1;for(int i=(1<<n)-1;i>=0;i--){int last=0;for(int j=1;j<=n;j++)if(i&(1<<(j-1))){if(!last||x[j]!=x[last])dp[i-(1<<(j-1))]=(dp[i-(1<<(j-1))]+dp[i])%mod;last=j;}}printf("%lld\n",dp[0]);return 0;
}