/* 题目大意:求1 - n范围内含有"49"的数的个数。 思路:记忆化搜索 */ #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <string.h> #include <string> using namespace std; const int NUMBER_LEN = 19; const int INDEX_LEN = 10; int cases, tot; //测试样数,tot数的长度 int num[NUMBER_LEN]; //储存每一位 long long n; __int64 dp[NUMBER_LEN][INDEX_LEN][2]; void init() //计算每一位数,1 <= n <= 2^63 - 1; { memset(dp, 0, sizeof(dp)); tot = 0; while (n) { num[tot++] = n % 10; n /= 10; } } __int64 solve(int pos, int pre, int flag, bool limit) { if (pos <= -1) return flag; //最后一位也搜索结束,返回flag(flag标记是否在之前出现了49) if (dp[pos][pre][flag] && !limit) return dp[pos][pre][flag]; //如果这种状态已经搜索过,返回结果 int x = limit ? num[pos] : 9; //取上限 __int64 res = 0; //计算结果 for (int i = 0; i <= x; i++) { res += solve(pos - 1, i, (pre == 4 && i == 9) || flag, (limit && i == x)); } if (!limit) dp[pos][pre][flag] = res; //记录结果 return res; } void input() { scanf("%d", &cases); while (cases--) { scanf("%I64d", &n); //输入 init(); //初始化 cout << solve(tot - 1, 0, 0, 1) << endl; //输出结果 } } int main() { input(); return 0; }
原文:http://blog.csdn.net/u011676717/article/details/38399341