测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A30283. 至多删 3 个字符

填空题 困难

题目描述

至多删 3 个字符

题目描述

给定一个全部由小写英文字母组成的字符串, 允许你至多删掉其中 3 个字符, 结果可能有多少种不同的字符串?

时间限制: 1 000        内存限制: 262144

输入

输入在一行中给出全部由小写英文字母组成的、 长度在区间 [4, 1000000 ] 内的字符串。

输出

在一行中输出至多删掉其中 3 个字符后不同字符串的个数。

样例输入

ababcc

样例输出

25

提示

样例 删掉 0 个字符得到 "ababcc"。 

删掉 1 个字符得到 "babcc", "aabcc", "abbcc","abacc" 和 "ababc"。 

删掉 2 个字符得到 "abcc", "bbcc", "bacc", "babc", "aacc","aabc", "abbc", "abac" 和 "abab"。

 删掉 3 个字符得到 "abc", "bcc", "acc", "bbc","bac", "bab", "aac", "aab", "abb" 和 "aba"。

参考答案

#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e6 + 10; int dp[N][4]; signed main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); string s, stemp; cin >> stemp; s.assign("0"); s.append(stemp); dp[0][0] = 1; for (int i = 1; i < s.size(); ++i) { for (int j = 0; j <= 3; ++j) { dp[i][j] = dp[i - 1][j]; if (j) dp[i][j] = dp[i][j] + dp[i - 1][j - 1]; for (int k = i - 1; k >= 1 && i - k <= j; --k) { if (s[k] == s[i]) { dp[i][j] = dp[i][j] - dp[k - 1][j - (i - k)]; break; } } } } int ans = 0; for (int i = 0; i <= 3; ++i) { ans = ans + dp[s.size() - 1][i]; } cout << ans << endl; return 0; }
上一题 下一题