C++/PTA 至多删三个字符

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

题目要求

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


输入格式:

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


输出格式:

在一行中输出至多删掉其中 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”。


解题思路

设 dp[i][j] 表示仅考虑前 i 个字符,选出了 j 个不同的字符的子序列的个数,则有:

image.png

其中第二个条件是根据题目的要求得到的,即所求子序列中不能存在连续的相同字符。

然后对于每一个位置 i,在本位置寻找符合条件的前一个字符 k,有:

image.png

也就是减去之前已经计算过,并且与当前字符相同的所有情况,以确保不存在连续的相同字符。

最终答案为 dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3],其中 n 是字符串 s 的长度。


代码

#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;
}



总结

本文使用动态规划算法解题,读者可躬身实践。

我是秋说,我们下次见。


目录
相关文章
|
4月前
|
存储 算法 编译器
【C++ 字符数组的模板特化】面向字符串的C++模板特化:理解与实践
【C++ 字符数组的模板特化】面向字符串的C++模板特化:理解与实践
94 1
|
4月前
|
对象存储 C++
在C++语言中字符串流
在C++语言中字符串流
36 2
|
4月前
|
存储 C++ 索引
C++ string容器-字符存取讲解
C++ string容器-字符存取讲解
63 0
|
4月前
|
C++
【PTA】L1-016 验证身份(C++)
【PTA】L1-016 验证身份(C++)
70 0
【PTA】L1-016 验证身份(C++)
|
4月前
|
编译器 C++
c++关键字与三字符组
c++关键字与三字符组
43 0
|
4月前
|
存储 C++
c++字符和不常见常量
c++字符和不常见常量
46 0
|
3月前
|
存储 C++
【PTA】L1-039 古风排版(C++)
【PTA】L1-039 古风排版(C++)
22 1
|
4月前
|
数据处理 C++
C++程序字符串流
C++程序字符串流
33 2
|
4月前
|
Java C++
部落(pta)(并查集) Java以及C++
部落(pta)(并查集) Java以及C++
35 2
|
21天前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
29 0