[Swust OJ 1097]--2014(数位dp)

题目链接:http://acm.swust.edu.cn/problem/1097/

 

Time limit(ms): 1000      Memory limit(kb): 32768
 

今年是2014年,所以小明喜欢2014的每一位数字(即:2,0,1,4),小明想知道在区间[l,r](包括l和r)中有多少个数中含有这4个数字(数字无前缀零)。

Description

多组数据。


每组数据输入2个数l,r(0<l<r<=10^9)

Input

输出占一行,即区间[l,r](包括l和r)中包含的满足条件的数的个数


 

Output
1
2
3
1 10
100 1024
 
Sample Input
1
2
3
0
1
 
Sample Output
输出换行请使用\r\n
Hint
swust第10届校赛
 
 
解题思路:就一个简单的数位dp,直接套模板就是了~~~
(不会的可以戳戳这里: http://www.cnblogs.com/zyxStar/p/4563830.html
 
代码如下:
 1 #include<iostream>

 2 #include<cstring>

 3 using namespace std;

 4 int dp[10][2][2][2][2];//返回各数状态

 5 int bit[10];  //数位dp

 6 int dfs(int pos, int s2, int s0, int s1, int s4, bool limit, bool fzero)

 7 {

 8     //注意前导零的影响

 9     if (pos == -1) return s2&&s0&&s1&&s4;

10     if (!limit&&!fzero&&~dp[pos][s2][s0][s1][s4])

11         return dp[pos][s2][s0][s1][s4];//条件判断

12     int end = limit ? bit[pos] : 9;

13     int ans = 0, i;

14     for (i = 0; i <= end; i++){

15         int now2 = s2, now0 = s0, now1 = s1, now4 = s4;

16         if (s2 == 0){

17             if (i == 2)

18                 now2 = 1;

19         }

20         if (s0 == 0){

21             if (!fzero&&i == 0)

22                 now0 = 1;

23         }

24         if (s1 == 0){

25             if (i == 1) 

26                 now1 = 1;

27         }

28         if (s4 == 0){

29             if (i == 4)

30                 now4 = 1;

31         }

32         ans += dfs(pos - 1, now2, now0, now1, now4, limit&&i == end, fzero&&!i);

33     }

34     return limit || fzero ? ans : dp[pos][s2][s0][s1][s4] = ans;

35 }

36 int calc(int n){

37     int len = 0;

38     while (n){

39         bit[len++] = n % 10;

40         n /= 10;

41     }

42     return dfs(len - 1, 0, 0, 0, 0, 1, 1);

43 }

44 int main(){

45     int l, r;

46     memset(dp, -1, sizeof(dp));

47     while (cin >> l >> r)

48         cout << calc(r) - calc(l - 1) << "\r\n";

49     return 0;

50 }
View Code

 

你可能感兴趣的:(dp)