题目链接:点击打开链接
题意:中文题目,很显然
思路:数位DP入门,DP函数有四个参量,当前位置,前一位的数字,前一位是否为6,前几位取值是否都是上限。dp[i][state]表示第i位在limit(limit对应第四个参量)取0时,该state状态下(state对应第三个参量)剩余位数(包括本位)取值满足条件的方案和。
// HDU 2089 不要62.cpp 运行/限制:0ms/1000ms
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int dp[10][2];
int upper, dig[10];
int DP(int pos, int pre, int state, int limit) {//位置 前一位的数字 前一位是否为6 前几位是否是上限
if (pos == -1) {
return 1;
}
if (!limit && dp[pos][state] != -1) {
return dp[pos][state];
}
int re = 0;
int top = limit ? dig[pos] : 9;
for (int i = 0; i <= top; i++) {
if (i == 4) continue;
if (pre == 6 && i == 2) continue;
re += DP(pos - 1, i, i == 6, limit && i == dig[pos]);
}
if (!limit) dp[pos][state] = re;
return re;
}
int solve(int num) {
upper = 0;
while (num) {
dig[upper++] = num % 10;
num /= 10;
}
return DP(upper - 1, -1, 0, 1);
}
int main(){
int n, m;
memset(dp, -1, sizeof(dp));//优化:dp数组在此初始化,能节省很多时间,因为在limit取0时,dp数组的取值只和数位有关,和测试数据的范围无关
while (scanf("%d%d", &n, &m) != EOF && n && m) {
printf("%d\n", solve(m) - solve(n - 1));
}
return 0;
}