HDU 4734 F(x) (数位dp)

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

题意:

给了个f(x)的定义:F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1,Ai是十进制数位,然后给出a,b求区间[0,b]内满足f(i)<=f(a)的i的个数。

思路:

dp[pos][sum]表示分析到第pos位上值还剩sum的个数,一开始sum设为f(a),之后不断减就可以了。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 const int INF = 0x3f3f3f3f;
14 const int maxn=100000+5;
15 
16 int a,r;
17 int tot;
18 int ans;
19 int dp[20][2*maxn];
20 int dig[30];
21 
22 int f(int x)
23 {
24     if(x==0) return 0;
25     int ans=f(x/10);
26     return ans*2+(x%10);
27 }
28 
29 int dfs(int pos, int sum, bool limit)
30 {
31     if(pos==-1) return sum>=0;
32     if(sum<0)  return 0;
33     if(!limit && dp[pos][sum]!=-1)  return dp[pos][sum];
34     int ans=0;
35     int up=limit?dig[pos]:9;
36     for(int i=0;i<=up;i++)
37     {
38         ans+=dfs(pos-1,sum-i*(1<<pos),limit && i==dig[pos]);
39     }
40     if(!limit)  dp[pos][sum]=ans;
41     return ans;
42 }
43 
44 int solve(int x)
45 {
46     int pos=0;
47     while(x)
48     {
49         dig[pos++]=x%10;
50         x/=10;
51     }
52     return dfs(pos-1,tot,1);
53 }
54 
55 int main()
56 {
57     //freopen("in.txt","r",stdin);
58     int T;
59     int kase=0;
60     scanf("%d",&T);memset(dp,-1,sizeof(dp));
61     while(T--)
62     {
63 
64         scanf("%d%d",&a,&r);
65         tot=f(a);
66         printf("Case #%d: %d
",++kase,solve(r));
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7456489.html