F(x)
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1422 Accepted Submission(s): 560
Problem Description
For a decimal number x with n digits (A
nA
n-1A
n-2 ... A
2A
1), we define its weight as F(x) = A
n * 2
n-1 + A
n-1 * 2
n-2 + ... + A
2 * 2 + A
1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).
Input
The first line has a number T (T <= 10000) , indicating the number of test cases.
For each test case, there are two numbers A and B (0 <= A,B < 10 9)
For each test case, there are two numbers A and B (0 <= A,B < 10 9)
Output
For every case,you should output "Case #t: " at first, without quotes. The
t is the case number starting from 1. Then output the answer.
Sample Input
3 0 100 1 10 5 100
Sample Output
Case #1: 1 Case #2: 2Case #3: 13
一开始dp[i][j]表示进行到i位,F(x)值<=F(A)的个数,这样的话,每次都要重新计算dp值,在500ms的时限下就TLE。
其实dp[i][j]的j应该是剩下未考虑的和。。
int dp[10][5000]; int F; int bit[20],len,t,l,r; inline int dfs(int i,bool e,int s){ if(s<0) return 0; if(i<0) return s>=0; if(!e && dp[i][s]!=-1) return dp[i][s]; int v=(e?bit[i]:9),ans=0; rep(j,0,v+1){ ans+=dfs(i-1,e&&(j==v),s-j*(1<<i)); } if(!e) dp[i][s]=ans; return ans; } inline int solve(int n){ if(n==0) return 0<=F; len=0; while(n){ bit[len++]=n%10; n/=10; } return dfs(len-1,1,F); } int main(){ clr(dp,-1); t=input(); rep(ca,1,t+1){ l=input(),r=input(); F=0;int i=0; while(l){ F+=(l%10)*(1<<i); i++;l/=10; } printf("Case #%d: %d\n",ca,solve(r)); } return 0; }