AtCoder Beginner Contest 215 E题
作者:
白墙
,
2021-08-23 17:47:26
,
所有人可见
,
阅读 365
首先命名字,因为dp的状态与上一个字母以及当前选择的字母的状态有关所以可以考虑用三维
dp[i][state][last], 表示当前处理到第i个字母,10个字母的选择状态为state,上一个字母last的方案数
对于第i个字母有选择和不选择两种状态
int x = s[i] - 'A';
dp[i][state][last] = dp[i - 1][state][last]表示不选择第i个字母
if(j == x) dp[i][state][last] += dp[i - 1][state][last];
然后还要考虑不同比赛的组合
对于不包含字母x的集合V,以及包含字母x的集合S有
dp[i][V | (1 << x)][x] += dp[i - 1][V][last]; 这里表示字母x是第一次加进来
最后目标
由于当处理到第n个字母的时候有多种状态,上一个字母也有多种情况所以需要将所有结果的方案总和全部加起来
#include <iostream>
#include <cstring>
#define mod 998244353
using namespace std;
int dp[1024][1024][10];
int n;
string s;
int main () {
cin >> n >> s;
for (int i = 1; i <= n; i ++) {
int x = s[i - 1] - 'A';
for (int state = 0; state < 1024; state ++) {
for (int j = 0; j < 10; j ++) {
dp[i][state][j] = dp[i - 1][state][j];
if (j == x)
{
dp[i][state][j] += dp[i - 1][state][j];
dp[i][state][j] %= mod;
}
}
}
for (int state = 0; state < 1024; state ++) {
if (state & (1 << x)) continue;
for (int j = 0; j < 10; j ++) {
dp[i][state | (1 << x)][x] += dp[i - 1][state][j];
dp[i][state | (1 << x)][x] %= mod;
}
}
dp[i][1 << x][x] ++;
dp[i][1 << x][x] %= mod;
}
long long res = 0;
for (int i = 0; i < 1024; i ++) {
for (int j = 0; j < 10; j ++)
{
res += dp[n][i][j];
res %= mod;
}
}
cout << res << endl;
return 0;
}