HDU3555 Bomb —— 数位DP

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


 

Bomb

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 18739    Accepted Submission(s): 6929

Problem Description
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
 

 

Input
The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.

The input terminates by end of file marker.
 

 

Output
For each test case, output an integer indicating the final points of the power.
 

 

Sample Input
3 1 50 500
 

 

Sample Output
0 1 15
Hint
From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499", so the answer is 15.

 

 



题解:

数位DP通用:dp[pos][sta1][sta2][……]

表示:当前位为pos,之前的状态为sta1*sta2*……stan。n为限制条件的个数。

回到此题,限制条件有两个: 1.上一位是否为4; 2.之前是否已经出现49。

类似题目:http://blog.csdn.net/dolfamingo/article/details/72848001



代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 const int mod = 1e9+7;
17 const int maxn = 100+10;
18 
19 LL n;
20 LL a[maxn], dp[maxn][3];
21 
22 LL dfs(int pos, int status, bool lim)
23 {
24     if(!pos) return status==2;
25     if(!lim && dp[pos][status]!=-1) return dp[pos][status];
26 
27     LL ret = 0;
28     int m = lim?a[pos]:9;
29     for(int i = 0; i<=m; i++)
30     {
31         int tmp_status;
32         if(status==2 || status==1 && i==9)
33             tmp_status = 2;
34         else if(i==4)
35             tmp_status = 1;
36         else
37             tmp_status = 0;
38 
39         ret += dfs(pos-1, tmp_status, lim&&(i==m));
40     }
41 
42     if(!lim) dp[pos][status] = ret;
43     return ret;
44 }
45 
46 int main()
47 {
48     int T;
49     scanf("%d",&T);
50     while(T--)
51     {
52         scanf("%lld",&n);
53         int p = 0;
54         while(n)
55         {
56             a[++p] = n%10;
57             n /= 10;
58         }
59         memset(dp,-1, sizeof(dp));
60         LL ans = dfs(p, 0, 1);
61         printf("%lld\n",ans);
62     }
63 }
View Code

 

posted on 2017-11-28 12:34  h_z_cong  阅读(153)  评论(0编辑  收藏  举报

导航