数位DP(基础,模板)

共两题

一:

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3555

所看代码来源:

https://blog.csdn.net/u012860063/article/details/46820639

Bomb

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


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.
 1 #include <cstdio>  
 2 #include <cstring>  
 3 #include <iostream>  
 4 #include <algorithm>  
 5 using namespace std;
 6 long long dp[25][3];
 7 int digite[25];
 8 long long n;
 9 //dp[i][j]:长度为i的数的第j种状态  
10 //dp[i][0]:长度为i但是不包含49的方案数  
11 //dp[i][1]:长度为i且不含49但是以9开头的数字的方案数  
12 //dp[i][2]:长度为i且包含49的方案数  
13 long long DFS(int pos,int status,int limit)
14 {
15     long long end;
16     if (pos<=0)
17     return status==2;//注意是==; 
18     if(!limit && dp[pos][status]!=-1)////对于有限制的询问我们是不能够记忆化的  
19         return dp[pos][status]; 
20     long long ans=0;
21     if (limit==0)
22         end=9;
23     else
24         end=digite[pos];
25         for (int i=0;i<=end;i++)
26         {
27             int nstatus=status;
28             if(status==0 && i==4)//高位不含49,并且末尾不是4 ,现在末尾添4返回1状态  
29             nstatus = 1;  
30             else if(status==1 && i!=4 && i!=9)//高位不含49,且末尾是4,现在末尾添加的不是4返回0状态  
31             nstatus = 0;  
32             else if(status==1 && i==9)//高位不含49,且末尾是4,现在末尾添加9返回2状态  
33             nstatus = 2; 
34             ans+=DFS(pos-1,nstatus,i==end&&limit);
35         }
36         if (!limit)
37         {
38             dp[pos][status]=ans;
39         }
40         return ans;
41 }
42 int cal(long long x)
43 {
44     int cnt=0;
45     while (x)
46     {
47         digite[++cnt]=x%10;
48         x=x/10;
49     }
50     digite[cnt+1]=0;
51     return cnt;
52 }
53 int main()
54 {
55     int T;
56     scanf("%d",&T);
57     while (T--)
58     {
59         memset(dp,-1,sizeof(dp));
60         scanf("%lld",&n);
61         long long len=cal(n);
62         long long ans=DFS(len,0,1);
63         printf("%lld\n",ans);
64     }
65     return 0;
66  } 

 

 

 二:进化版

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3652

所看博客:https://blog.csdn.net/qq_33583069/article/details/51842294

B-number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8032    Accepted Submission(s): 4738


Problem Description

 

A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.

 

 


Input

 

Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).

 

 


Output

 

Print each answer in a single line.

 

 


Sample Input

 

13 100 200 1000

 

 


Sample Output

 

1 1 2 2

 

 1 #include <cstdio>  
 2 #include <cstring>  
 3 #include <iostream>  
 4 #include <algorithm>  
 5 using namespace std;
 6 long long dp[25][15][3];
 7 //dp[i][j][k]
 8 //i:数位
 9 //j:余数
10 //k:3种操作状况,0:末尾不是1,1:末尾是1,2:含有13
11 int digite[25];
12 long long n;
13 long long DFS(int pos,int mod,int status,int limit)
14 {
15     long long end;
16     if (pos<=0)
17     return status==2&&mod==0;//注意是==; 
18     if(!limit && dp[pos][mod][status]!=-1)
19         return dp[pos][mod][status]; 
20     long long ans=0;
21     if (limit==0)
22         end=9;
23     else
24         end=digite[pos];
25         for (int i=0;i<=end;i++)
26         {
27             int modx=(mod*10+i)%13;//巧用余数
28             int nstatus=status;
29             if(status==0 && i==1)
30             nstatus = 1;  
31             else if(status==1 && i!=1 && i!=3)
32             nstatus = 0;  
33             else if(status==1 && i==3) 
34             nstatus = 2; 
35             ans+=DFS(pos-1,modx,nstatus,i==end&&limit);
36         }
37         if (!limit)
38         {
39             dp[pos][mod][status]=ans;
40         }
41         return ans;
42 }
43 int cal(long long x)
44 {
45     int cnt=0;
46     while (x)
47     {
48         digite[++cnt]=x%10;
49         x=x/10;
50     }
51     digite[cnt+1]=0;
52     return cnt;
53 }
54 int main()
55 {
56     int T;
57     while (scanf("%lld",&n)!=EOF)
58     {
59         memset(dp,-1,sizeof(dp));
60         long long len=cal(n);
61         long long ans=DFS(len,0,0,1);
62         printf("%lld\n",ans);
63     }
64     return 0;
65  } 
View Code

 

 

 

posted @ 2018-04-29 11:33  jealous-boy  阅读(106)  评论(0编辑  收藏  举报