HDU4734(数位dp)
F(x)
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4423 Accepted Submission(s): 1632
Problem Description
For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).
Input
The first line has a number T (T <= 10000) , indicating the number of test cases.
For each test case, there are two numbers A and B (0 <= A,B < 109)
For each test case, there are two numbers A and B (0 <= A,B < 109)
Output
For every case,you should output "Case #t: " at first, without quotes. The t is the case number starting from 1. Then output the answer.
Sample Input
3
0 100
1 10
5 100
Sample Output
Case #1: 1
Case #2: 2
Case #3: 13
Source
1 //2016.8.31 2 #pragma comment(linker, "/STACK:1024000000,1024000000") 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 7 using namespace std; 8 9 int dp[20][10000], bit[20], a, b;//dp[i][j]表示第i位<=j的数目 10 11 int F(int a) 12 { 13 int ans = 0, len = 0; 14 while(a) 15 { 16 ans += (a%10)*(1<<len); 17 len++; 18 a /= 10; 19 } 20 return ans; 21 } 22 23 int dfs(int pos, int num, int fg) 24 { 25 if(pos == -1)return num>=0; 26 if(num < 0)return 0; 27 if(!fg && dp[pos][num]!=-1)//记忆化搜索 28 return dp[pos][num]; 29 int ans = 0; 30 int ed = fg?bit[pos]:9; 31 for(int i = 0; i <= ed; i++) 32 ans+=dfs(pos-1, num-i*(1<<pos), fg&&i==ed); 33 if(!fg)dp[pos][num] = ans; 34 return ans; 35 } 36 37 int solve(int b) 38 { 39 int len = 0; 40 while(b) 41 { 42 bit[len++] = b%10; 43 b /= 10; 44 } 45 int ans = dfs(len-1, F(a), 1); 46 return ans; 47 } 48 49 int main() 50 { 51 int T, kase = 0; 52 cin>>T; 53 memset(dp, -1, sizeof(dp)); 54 while(T--) 55 { 56 scanf("%d%d", &a, &b); 57 int ans = solve(b); 58 printf("Case #%d: %d\n", ++kase, ans); 59 } 60 61 return 0; 62 }