给你一个数字串,问你有多少个子序列构成的数字可以被3整除(子序列是在原来序列中找一部分组成的序列,不一定连续) 答案对1e9+7取模 输入格式: 输入一个字符串,由数字构成,长度小于等于50 输出格式: 输出一个整数c++
时间: 2024-12-29 15:34:16 浏览: 10
这是一个关于动态规划的问题,我们可以用C++来解决。首先,我们需要遍历给定的数字串,并维护两个辅助计数器:`dp0`表示当前子序列结束位置之前能被3整除的子序列数量,`dp1`表示当前子序列结束位置之前能被3除余1的子序列数量,`dp2`表示能被3除余2的子序列数量。
对于每个字符,我们更新计数器如下:
- 如果字符是3的倍数,`dp0`加1,同时将`dp1`和`dp2`清零,因为新的子序列开始可以覆盖掉之前的非3倍数部分。
- 如果字符是一次余1,`dp1`加1,`dp0`不变,因为新的子序列可以继续前一个余1的子序列。
- 如果字符是一次余2,`dp2`加1,`dp0`不变,同理。
最后,总的结果就是`dp0 + dp1 + dp2`,为了满足题目要求,结果需要对1e9 + 7取模。
C++伪代码示例:
```cpp
#include <iostream>
#include <vector>
int solve(const std::string& digits) {
int n = digits.size();
std::vector<int> dp(3, 0);
for (char c : digits) {
int num = c - '0';
dp[(num + dp[1]) % 3] = (dp[(num + dp[1]) % 3] + 1) % (1e9 + 7); // 取模操作
dp[(num - dp[2]) % 3] = (dp[(num - dp[2]) % 3] + 1) % (1e9 + 7); // 取模操作
dp[2] = (dp[2] + 1) % (1e9 + 7); // 如果不是3的倍数,dp2只增加1
}
return (dp[0] + dp[1] + dp[2]) % (1e9 + 7);
}
int main() {
std::string input;
std::cin >> input;
int result = solve(input);
std::cout << "可以被3整除的子序列数量:" << result << "\n";
return 0;
}
```
阅读全文