数位DP经典题
照着网上的模板打的,使用记忆化搜索,记录当前位的数字限制,上一个数字,state则构成dp的一种状态(上一位是否为6)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
int a[25];
LL dp[25][2];
inline int read(){
int k = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){k = k*10 + ch - '0'; ch = getchar();}
return k * f;
}
LL dfs(int pos, int last, int state, bool limit){
if(pos == -1) return 1;
if(!limit && dp[pos][state] != -1) return dp[pos][state];
int up = limit?a[pos]:9;
LL ret = 0;
for(int i = 0; i <= up; i++){
if(i == 4) continue;
else if(last == 6 && i == 2) continue;
ret += dfs(pos - 1, i, i == 6 ? 1 : 0, limit && i == a[pos]);
}
if(!limit) dp[pos][state] = ret;
return ret;
}
LL solve(LL x){
int pos = 0;
while(x){
a[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, 0, 0, true);
}
int main(){
int a = read(), b = read();
while(a || b){
memset(dp, -1, sizeof(dp));
printf("%lld\n", solve(b) - solve(a - 1));
a = read(), b = read();
}
return 0;
}