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