HDU 4734 F(x)
F(x)
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 768 Accepted Submission(s): 296
Total Submission(s): 768 Accepted Submission(s): 296
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: 2
Case #3: 13
Source
Recommend
liuyiding
很不错的dp题目,折磨好几天后终于ac了
很不错的dp题目,折磨好几天后终于ac了
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define N 5000 #define M 10 using namespace std; int dp[M][M][N]; int a[M],b[M]; int main() { a[1]=1; for(int i=2;i<=9;i++) { a[i] = a[i-1]*2; } memset(dp,0,sizeof(dp)); for(int i=0;i<=9;i++) { for(int j=i;j<=4608;j++) { dp[1][i][j]=1; } } for(int i=2;i<=9;i++) { for(int j=0;j<=9;j++) { for(int x=a[i]*j;x<=4608;x++) { for(int y=0;y<=9;y++) { dp[i][j][x]+=(dp[i-1][y][x-a[i]*j]); } } } } int t,cas=1; scanf("%d",&t); while(t--) { int n,m; scanf("%d %d",&n,&m); int s=0,base=1; while(n!=0) { s+=((n%10)*base); base=base*2; n=n/10; } int Top=0,com=0; base=1; while(m!=0) { b[Top++] = m%10; com+=(b[Top-1]*base); base=base*2; m = m/10; } int res =0; if(com<=s) { res++; } for(int i=Top-1;i>=0;i--) { int x = b[i]; for(int j=0;j<=x-1;j++) { res+=(dp[i+1][j][s]); } s-=(x*a[i+1]); if(s<0) { break; } } printf("Case #%d: %d\n",cas++,res); } return 0; }