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 }