HDU 4734——F(x)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4734
题意:数i在0~B的范围内,求F(i)小于F(A)的个数 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1
先把F(A)算出来=tot,然后按位计算,如果num(当前F(pos)<=tot,方案数+1 返回1,如果num>tot,返回0)
dp[pos][num] 的状态表示为dp[当前第几位][最大值tot-当前f(i)]
上代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 ll a[109];
5 ll dp[20][10009];
6 ll tot;
7 ll dfs(ll pos,ll num,bool limit)
8 {
9 if(pos==0) return num<=tot;
10 if(num>tot) return 0;
11 if(!limit&&dp[pos][tot-num]!=-1) return dp[pos][tot-num];
12 ll up=limit?a[pos]:9;
13 ll res=0;
14 for(ll i=0; i<=up; i++)
15 {
16 res+=dfs(pos-1,num+i*(1<<(pos-1)),limit&&i==a[pos]);
17 }
18 if(!limit) dp[pos][tot-num]=res;
19 return res;
20 }
21 ll solve(ll x)
22 {
23 ll pos=0;
24 while(x)
25 {
26 a[++pos]=x%10;
27 x/=10;
28 }
29 return dfs(pos,0,1);
30 }
31 int main()
32 {
33 memset(dp,-1,sizeof(dp));
34 int t;
35 scanf("%d",&t);
36 for(int i=1;i<=t;i++)
37 {
38 ll a,b;
39 scanf("%lld%lld",&a,&b);
40 ll tem=0,cnt=1;
41 tot=0;
42 while(a)
43 {
44 tem=(a%10);
45 tot+=tem*cnt;
46 a/=10;
47 cnt*=2;
48 }
49 // printf("%lld\n",tot);
50 printf("Case #%d: %lld\n",i,solve(b));
51 }
52 return 0;
53 }
来源:https://www.cnblogs.com/YangKun-/p/12633592.html