【动态规划】P10694 [SNCPC2024] 双子序列
对于任意一个满足要求(即子序列中包含
动态规划,记
- 若
S_i={S_1}_{j} ,有f_{i,j,k}\leftarrow f_{i,j,k}+\displaystyle \sum_{t=1}^{i-1} f_{t,j-1,k} 。 - 若
S_i={S_2}_{k} ,则有f_{i,j,k}\leftarrow f_{i,j,k}+\displaystyle \sum_{t=1}^{i-1} f_{t,j,k-1} 。 - 若
S_i={S_1}_{j} 且S_i={S_2}_{j} ,则有f_{i,j,k}\leftarrow f_{i,j,k}+\displaystyle \sum_{t=1}^{i-1} f_{t,j-1,k-1} 。
但是枚举转移单次
:::success[AC 代码]
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 998244353;
const int maxm = 25;
int n, len1, len2;
string s, s1, s2;
long long dp[maxn][maxm][maxm], pre[maxm][maxm], ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> s >> s1 >> s2;
n = s.length();
len1 = s1.length();
len2 = s2.length();
s = " " + s;
s1 = " " + s1;
s2 = " " + s2;
for (int i = 1; i <= n; i++)
{
if (s[i] == s1[1])
dp[i][1][0] = i;
if (s[i] == s2[1])
dp[i][0][1] = i;
if (s[i] == s1[1] && s[i] == s2[1])
dp[i][1][1] = i;
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= len1; j++)
{
for (int k = 0; k <= len2; k++)
{
pre[j][k] = (pre[j][k] + dp[i - 1][j][k]) % mod;
}
}
for (int j = 0; j <= len1; j++)
{
for (int k = 0; k <= len2; k++)
{
if (j > 0 && s1[j] == s[i])
dp[i][j][k] = (dp[i][j][k] + pre[j - 1][k]) % mod;
if (k > 0 && s2[k] == s[i])
dp[i][j][k] = (dp[i][j][k] + pre[j][k - 1]) % mod;
if (j > 0 && k > 0 && s1[j] == s[i] && s2[k] == s[i])
dp[i][j][k] = (dp[i][j][k] + pre[j - 1][k - 1]) % mod;
}
}
ans = (ans + dp[i][len1][len2] * (n - i + 1)) % mod;
}
cout << ans << "\n";
return 0;
}
代码经过了格式化。 :::