题解:AT_abc425_f [ABC425F] Inserting Process

这个 \(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;
}
posted @ 2025-09-28 17:09  Igunareo  阅读(44)  评论(0)    收藏  举报