现在的位置: 首页 > 综合 > 正文

HDU 3652 B-number(数位DP)

2018年10月13日 ⁄ 综合 ⁄ 共 753字 ⁄ 字号 评论关闭

数位DP,DP[I][J][K][L]表示到第i位,末尾为j,mod13为k,l的01表示是否出现过13了,然后就是数位DP的状态转移即可

代码:

#include <cstdio>
#include <cstring>

char num[12];

int n, dp[12][10][14][2];

int main() {
	while (~scanf("%s", num)) {
		n = strlen(num);
		memset(dp, 0, sizeof(dp));
		int pre = 0, mod = 0, flag = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < 10; j++) {
				for (int k = 0; k < 10; k++) {
					for (int x = 0; x < 13; x++) {
						dp[i + 1][j][(x * 10 + j) % 13][1] += dp[i][k][x][1];
						if (j == 3 && k == 1) dp[i + 1][j][(x * 10 + j) % 13][1] += dp[i][k][x][0];
						else dp[i + 1][j][(x * 10 + j) % 13][0] += dp[i][k][x][0];
					}
				}
			}
			for (int j = 0; j < num[i] - '0'; j++) {
				if (flag || (j == 3 && pre == 1)) dp[i + 1][j][(mod * 10 + j) % 13][1]++;
				else dp[i + 1][j][(mod * 10 + j) % 13][0]++;
			}
			if (pre == 1 && num[i] - '0' == 3) flag = 1;
			pre = num[i] - '0';
			mod = (mod * 10 + num[i] - '0') % 13;
		}
		int ans = (flag && mod == 0);
		for (int i = 0; i < 10; i++)
				ans += dp[n][i][0][1];
		printf("%d\n", ans);
	}
	return 0;
}

抱歉!评论已关闭.