数位DP入门题 hdu 2089 hdu 3555

hdu 2089 不要62

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089

题意:对于每次给出的一个区间,找出区间内多少个数字没有出现62和4。

思路:

数位DP入门题,对于dfs设置3个参数。

一个表示现在进行到第几位,

一个表示前一个标记状态,这里表示上一位是不是6。

一个表示是否现在是这位可以取到的最大的数字。

如果上一位是6,那么这位不可以取2。且当前位都不可以取4。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int dp[10][2], num[10];
 4 int dfs(int cur, int state, int limit)
 5 {
 6     if(cur < 0) return 1;
 7     if(!limit && dp[cur][state] != -1) return dp[cur][state];
 8     
 9     int ret = 0;
10     int up = limit?num[cur]:9;
11     for(int i = 0; i <= up; i++)
12     {
13         if(state == 1 && i == 2 || i == 4) continue;
14         else ret += dfs(cur-1, i == 6, limit && i == up);
15     }
16     if(!limit) dp[cur][state] = ret;
17     return ret;
18     
19 }
20 int slove(int x)
21 {
22     memset(dp, -1, sizeof(dp));
23     int cnt = 0;
24     while(x)
25     {
26         num[cnt++] = x % 10;
27         x /= 10;
28     }
29     return dfs(cnt-1, 0, 1);
30 }
31 int main() 
32 {
33   //  freopen("in.txt", "r", stdin);
34   //  freopen("out.txt", "w", stdout);
35     int n, m;
36     while(~scanf("%d%d", &n, &m) && n+m)
37     {
38         printf("%d\n", slove(m) - slove(n-1));
39     }
40     return 0;
41 }

 

hdu 3555 bomb

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555

题意:找出1-N中出现49的数字个数。

思路:和上题差不多,如果前几位出现4,则这位不能出现9。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int T;
 4 int num[30];
 5 long long dp[30][2];
 6 long long dfs(int cur, int state, int limit)
 7 {
 8     if(cur < 0) return 1;
 9     if(!limit && dp[cur][state] != -1) return dp[cur][state];
10     
11     long long ret = 0;
12     int up = limit?num[cur]:9;
13     for(int i = 0; i <= up; i++)
14     {
15         if(state && i == 9) continue;
16         ret += dfs(cur-1, i == 4, limit && i == up);
17     }
18     if(!limit) dp[cur][state] = ret;
19     return ret;
20 }
21 long long slove(long long x)
22 {
23     memset(dp, -1, sizeof(dp));
24     int cnt = 0;
25     while(x)
26     {
27         num[cnt++] = x%10;
28         x /= 10;
29     }
30     return dfs(cnt-1, 0, 1);
31 }
32 long long N;
33 int main() 
34 {
35   // freopen("in.txt", "r", stdin);
36   //  freopen("out.txt", "w", stdout);
37     scanf("%d", &T);
38     while(T--)
39     {
40         scanf("%lld", &N);
41         printf("%lld\n", N+1-slove(N));
42     }
43     
44     return 0;
45 }

 

posted @ 2016-03-02 08:51  下周LGD该赢了吧  阅读(166)  评论(0编辑  收藏  举报