被3整除的子序列(线性dp)

题目链接

登录—专业IT笔试面试备考平台_牛客网

题号:NC21302
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模

输入描述:

输入一个字符串,由数字构成,长度小于等于50

输出描述:

输出一个整数

示例

输入

132

输出

3

备注:

n为长度
子任务1: n <= 5
子任务2: n <= 20
子任务3: 无限制

解题思路

1. 一个数能被3整除,说明这个数每位的和是3的倍数

2. 利用动态规划的思想,dp[i][[j] 表示前i位,模3是j的数的个数。

代码

#include
using namespace std;
const int MOD = 1e9+7;
long long dp[51][3];
int main() {
	string str;
	cin >> str;
	for (int i = 1; i <= str.size(); i++) {
		int value = str[i-1] - '0';
		if (value % 3 == 0) {
			dp[i][0] = (1 + dp[i-1][0] + dp[i-1][0])  % MOD;
			dp[i][1] = (dp[i-1][1] + dp[i-1][1]) % MOD;
			dp[i][2] = (dp[i-1][2] + dp[i-1][2]) % MOD;
		}
		if (value % 3 == 1) {
			dp[i][0] = (dp[i-1][0] + dp[i-1][2]) % MOD;
			dp[i][1] = (1+dp[i-1][1] + dp[i-1][0]) % MOD;
			dp[i][2] = (dp[i-1][2] + dp[i-1][1]) % MOD;
		}
		if (value % 3 == 2) {
			dp[i][0] = (dp[i-1][0] + dp[i-1][1]) % MOD;
			dp[i][1] = (dp[i-1][1] + dp[i-1][2]) % MOD;
			dp[i][2] = (1+dp[i-1][2] + dp[i-1][0]) % MOD;
		}
	}
	cout << dp[str.size()][0] << endl;
	return 0;
}

你可能感兴趣的:(dp,c++,算法,动态规划,线性dp)