昨天做了一道很奇怪的数字题,不知道怎么做,今天才知道是数位DP ……我来学习学习。
传送门
大意:给定区间
思路:做这道题我们就要用到数位DP了,我们可以线预处理出一个F数组。用
上代码:
#include<cstdio>
#include<cstring>
int f[10][10], n, m;
int bit[10];
int dp(int len)
{
int ans = 0;
bit[len + 1] = 0;
for(int i = len; i > 0; i --){
for(int j = 0; j < bit[i]; j ++){
if(j == 2 && bit[i+1] == 6) continue;
ans += f[i][j];
}
if(bit[i] == 4||(bit[i] == 2 && bit[i+1] == 6)) //找到了4或者连续的62说明后面的数都是接在4和62后面的,所以直接退出
break;
}
return ans;
}
int main()
{
f[0][0] = 1;
for(int i = 1; i <= 7; i ++)
for(int j = 0; j <= 9; j ++)
{
if(j == 4) continue;
for(int k = 0; k <= 9; k ++)
{
if((j == 6 && k == 2) || k == 4) continue;
f[i][j] += f[i-1][k];
}
}
while(~scanf("%d%d", &n, &m) && n + m) {
m ++; //因为我们只算了[1,r)的,所以上去间 ++
int t1 = n, t2 = m, l1 = 0, l2 = 0;
while(t1)
{
l1 ++;
bit[l1] = t1 % 10;
t1 /= 10;
}
t1 = dp(l1);
while(t2)
{
l2 ++;
bit[l2] = t2 % 10;
t2 /= 10;
}
t2 = dp(l2);
printf("%d\n", t2 - t1);
}
return 0;
}