[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 }
如果这是你所爱的,就不要让自己后悔~~~