[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

 

posted @ 2015-06-09 16:22  繁夜  阅读(262)  评论(0编辑  收藏  举报