开始学一下数位dp 有一个地方不理解 先标记一下
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long double ld;
const int N = 10;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = acos (-1.0);
#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)
int dp[N][2], bit[N];
int dfs (int len, bool is6, bool ismax);
int calc (int n);
int main ()
{
int n, m;
met (dp, -1);
while (cin >> m >> n, m || n)
{
cout << calc (n) - calc (m-1) << endl;
}
return 0;
}
int dfs (int len, bool is6, bool ismax) // 长度 状态 是否达到上限
{
if (len == 0) return 1; //如果长度为0 证明此串合法
if (!ismax && dp[len][is6] >= 0) return dp[len][is6]; //如果不是最高位 且已经搜索过 直接返回
// 为什么要求不是最高位 才能直接返回呢
//比如 5431 对于4xxx 3xxx 当len为3的时候都可以直接返回 因为之前已经计算过
//而5xxx 最多只能取到5431 必须要重新计算
int cnt = 0, maxnum = (ismax ? bit[len] : 9); //如果是最高位 只能取到bit[len]
for (int i=0; i<=maxnum; i++) //枚举
{
if (i == 4 || (is6 && i == 2)) continue; //不能有4 且不能有62
cnt += dfs (len - 1, i == 6, ismax && i == maxnum); // 递归搜索
}
return ismax ? cnt : dp[len][is6] = cnt;// 根据ismax来决定是否记录dp
//(比如dp[3][1]记录的是6xx的所有数,即从600到699中的符合条件的数的个数)
}
int calc (int n)
{
int len = 0;
while (n)
{
bit[++len] = n % 10;
n /= 10;
}
return dfs (len, false, true);
}