这道题目,虽然不是第一道数位dp,但搞了好几天,思路倒是简单,主要是再求一个数下有多少满足要求的判断太多了,昨天晚上已经过了很多数据,知道还有些判断有问题,今天早上改 了一下,AC了;
思路:1,先求出 dp[len][0] (代表长度为len,满足条件的个数) ;dp[len][1] (长度为len,满足条件,但开头为2), dp[len][2] (长度为len,满足条件,开头bu为2);
2,对每一个数,求出该数下有多少满足条件;(最难的一步,很容易搞错,必须仔细在仔细)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
int dp[8][3] ;
const int N = 1000000 ;
int fun(int x) {
int sum = 0 ;
bool flag = false ;
for(int i = N , len = 6 ; len >= 0 ; i/= 10 , --len) {
int f = x/i ;
if(f == 0) { flag = false ; continue;}
if(len == 0) {
sum += f ;
if(flag && f > 1) --sum ;
if(f > 3) --sum ;
break ;
}
if(flag) {
if(f <= 2) sum += f*dp[len][0] ;
if(f == 2) {--sum ;break ;}
if(f == 3) sum += (f-1)*dp[len][0] ;
if(f > 4 && f <= 6) sum += (f-2)*dp[len][0] ;
if(f == 4) {sum += (f-1)*dp[len][0] - 1 ; break ;}
if(f > 6) sum += (f-3)*dp[len][0] + dp[len][2] ;
if(f == 6) flag = true;
else flag = false ;
}else {
if(f < 4) sum += dp[len][0]*f ;
if(f == 4) {sum += f*dp[len][0] - 1 ; break ;}
if(f > 4 && f <= 6) sum += (f-1)*dp[len][0] ;
if(f > 6) sum += (f-2)*dp[len][0] + dp[len][2] ;
if(f == 6) flag = true ;
else flag = false ;
}
x%= i ;
}
return sum ;
}
int main() {
dp[1][0] = 9 ;
dp[1][1] = 1 ;
dp[1][2] = 8 ;
for(int i = 2 ; i < 8 ; ++i) {
dp[i][1] = dp[i-1][0] ;
dp[i][2] = dp[i-1][1]*7 + dp[i-1][2]*8 ;
dp[i][0] = dp[i][1] + dp[i][2] ;
}
int a , b ;
while(scanf("%d%d",&a ,&b )== 2 && a + b) {
int s1 = fun(a-1) ;
int s2 = fun(b) ;
printf("%d\n" ,s2 - s1);
}
}
再贴一个看了大牛的博客后写代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
int dp[8][3] ;
/*
* dp[i][0] 不含有62和4的个数
* dp[i][1] 不含有62和4,以2开头
* dp[i][2] 含有62或4
*/
void init() {
dp[0][0] = 1 ;
dp[1][0] = 9 ; dp[1][1] = 1 ; dp[1][2] = 1 ;
for(int i = 2 ; i < 8 ; ++i) {
dp[i][0] = dp[i-1][0]*9 - dp[i-1][1] ;
dp[i][1] = dp[i-1][0] ;
dp[i][2] = dp[i-1][2]*10 + dp[i-1][0] + dp[i-1][1] ;
}
}
int process(int x) {
int len = 0 ;
int tmp = x ;
int bit[9] ;
while(x) {
bit[++len] = x%10 ;
x /= 10 ;
}
bit[len+1] = 0 ;
bool flag = false ;
int sum = 0 ;
for(int i = len ; i > 0 ; --i) {
sum += bit[i]*dp[i-1][2] ;
if(flag) sum += bit[i]*dp[i-1][0] ;
else {
if(bit[i] > 6) sum += dp[i-1][1] ;
if(bit[i] > 4) sum += dp[i-1][0] ;
if(bit[i+1] == 6 && bit[i] > 2) {
sum += dp[i][1] ;
}
}
if(bit[i+1] == 6 && bit[i] == 2 || bit[i] == 4) flag = true ;
}
if(flag) ++sum ;
return tmp - sum ;
}
int main() {
init() ;
int n , m ;
while(scanf("%d%d",&n ,&m)==2 && n + m) {
printf("%d\n" , process(m) - process(n-1)) ;
}
}