题意:

   一个非负整数的十进制位是这样的 (AnAn-1An-2 ... A2A1),定义F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1。给出A和B,问[0,B]中有几个整数x的F(x)值<=F(A)?

 

 

思路:

  算一下就知道F(x)值不会超过512*9,而B仅仅有8位十进制数,那么8*512*9就可以算出所有的统计了。对于每个询问,先计算F(A)的值,然后统计小于此值有几个就行了。统计的复杂度也是很低的。若是以前缀和来统计后面的个数的话,要么TLE,要么WA。

 

 


HDU 4734 F(x) (数位DP,基础)_数位DPHDU 4734 F(x) (数位DP,基础)_#define_02


1 #include <bits/stdc++.h>
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5 #include <cmath>
6 #include <map>
7 #include <algorithm>
8 #include <vector>
9 #include <iostream>
10 #define pii pair<int,int>
11 #define INF 0x7f3f3f3f
12 #define LL long long
13 #define ULL unsigned long long
14 using namespace std;
15 const double PI = acos(-1.0);
16 const int N=10;
17
18 int f[N][5120], bit[N], limit;
19 //[第几位][上界]
20
21 int dfs(int i,int sum,bool e)
22 {
23 if(i==0) return sum>=0;
24 if(sum<0) return 0;
25 if(!e && ~f[i][sum] ) return f[i][sum];
26
27 int ans=0;
28 int u= e? bit[i]: 9;
29 for(int d=0; d<=u; d++)
30 ans+=dfs(i-1, sum-d*(1<<i-1), e&&d==u);
31
32 return e? ans: f[i][sum]=ans;
33 }
34
35 int cal(int n)
36 {
37 if(n<0) return 0;
38 if(n==0) return 1;
39
40 int len=0;
41 while(n) //拆数
42 {
43 bit[++len]=n%10;
44 n/=10;
45 }
46 return dfs(len, limit, true);
47
48 }
49 void pre_cal(int n)
50 {
51 int len=0;
52 while(n) //拆数
53 {
54 bit[++len]=n%10;
55 n/=10;
56 }
57 limit=0;
58 for(int i=1; i<=len; i++) limit+=bit[i]*(1<<i-1);
59 }
60
61 int main()
62 {
63 //freopen("input.txt","r",stdin);
64 memset(f, -1, sizeof(f));
65 int t, n, Case=0;
66 cin>>t;
67 while( t-- )
68 {
69 scanf("%d%d",&limit,&n);
70 pre_cal(limit);
71 printf("Case #%d: %d\n", ++Case, cal(n));
72 }
73 return 0;
74 }

AC代码

 


作者:​​xcw0754​