题意
求区间[L,R]内含有4或者含有相邻62的数的个数。
思路
和上一道题目
HDU 3555一样,只需要改变一下状态转移即可。
第一道自己独立写出来的数位DP,而且还1Y~~^_^
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, m) for (int i = begin; i < begin+m; i ++)
using namespace std;
typedef long long LL;
typedef vector <int> VI;
typedef set <int> SETI;
typedef queue <int> QI;
typedef stack <int> SI;
const int oo = 0x7fffffff;
const int maxn = 10;
int dp[maxn][maxn][2];
vector <int> num;
int dfs(int pos, int pre, bool flag, bool limit){
if (pos == -1) return 1-flag;
if (!limit && ~dp[pos][pre][flag]) return dp[pos][pre][flag];
int end = limit?num[pos]:9;
int res = 0;
for (int i = 0; i <= end; i ++){
res += dfs(pos-1, i, i == 4 || (i == 2 && pre == 6) || flag, limit && (i == end));
}
if (!limit)
dp[pos][pre][flag] = res;
return res;
}
int cal(int x){
num.clear();
while(x){
num.push_back(x % 10);
x /= 10;
}
MEM(dp, -1);
return dfs(num.size()-1, 0, 0, 1);
}
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int n, m;
while(scanf("%d %d", &n, &m), n+m){
printf("%d
", cal(m) - cal(n-1));
}
return 0;
}
[/cpp]