题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555
思路分析:该问题要求求解1—N中的数中含有49的数的个数,可以使用DFA来递推dp公式;详细解释点击链接查看;
代码如下:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int MAX_N = 20 + 10; long long dp[MAX_N][3]; int digit[MAX_N]; int NextState(int cur_state, int next_char) { if (cur_state == 0) { if (next_char == 4) cur_state++; } else if (cur_state == 1) { if (next_char == 9) ++cur_state; else if (next_char != 4) --cur_state; } return cur_state; } int main() { int case_times; long long n; scanf("%d", &case_times); while (case_times--) { int cur_state = 0, count = 0; int len = 0; long long ans = 0, temp_value = 0; scanf("%I64d", &n); temp_value = ++n; while (temp_value) { digit[++len] = temp_value % 10; temp_value /= 10; } for (int i = len; i >= 1; -- i) { ++count; for (int j = 0; j < digit[i]; ++ j) { memset(dp, 0, sizeof(dp)); dp[count][NextState(cur_state, j)] = 1; for (int k = count + 1; k <= len; ++ k) { dp[k][0] = 9 * dp[k-1][0] + 8 * dp[k-1][1]; dp[k][1] = dp[k-1][0] + dp[k-1][1]; dp[k][2] = dp[k-1][1] + 10 * dp[k-1][2]; } ans += dp[len][2]; } cur_state = NextState(cur_state, digit[i]); } printf("%I64d\n", ans); } return 0; }
时间: 2024-11-11 05:42:13