专栏文章
题解:AT_abc425_f [ABC425F] Inserting Process
AT_abc425_f题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minqlvjk
- 此快照首次捕获于
- 2025/12/02 06:45 3 个月前
- 此快照最后确认于
- 2025/12/02 06:45 3 个月前
解法
考虑状压 DP。
首先,如果一个一个添字符是很难做的,那我们可以反着来,考虑一个一个删字符。
设 表示已经删除了的字符集合为 ,总共有多少种可能的删除方法。
对于每个 ,很明显他能对所有比 多删了一个字符的 造成贡献,可以 枚举,所以总时间复杂度为 。
但你以为这样就结束了吗?不,如果你尝试运行样例,你就会发现答案比正确答案多了一点。
为什么呢?我们可以发现,有些删除字符的操作序列看起来是一样的。比如有字符串
aabb,先删第 位和先删第 位是一样的。为了解决这种情况,我们规定如果当前字符串有多个字符相同,那么就必须从最左边开始删,这样问题就解决了。代码
CPP#include <bits/stdc++.h>
#define int long long
const int N = 25;
const int Mod = 998244353;
using namespace std;
int n;
string t;
int f[1 << N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> t;
f[0] = 1;
for (int S = 0; S < 1 << n; S++)
{
int pre = -1;
for (int i = 0; i < n; i++)
{
if (S & (1 << i))
{
continue;
}
if (pre == -1 || t[i] != t[pre])
{
int T = S | (1 << i);
f[T] += f[S];
f[T] %= Mod;
}
pre = i;
}
}
cout << f[(1 << n) - 1];
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...