HDU 4734 —— F(x)

Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
 

Description

For a decimal number x with n digits (A nn-1n-2 ... A 21), 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)
 

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
 
这题很关键的一点是要懂得,将终点统一为>=0
回顾很多的“数位DP”问题,它们的终点都是一致的!
 
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int b[10], num[10];
int dp[10][9*((1<<10)-1)];

int dfs(int u, int f, bool limit)
{
    if(u < 1)    return 1;
    if(!limit && dp[u][f] != -1)    return dp[u][f];
    
    int maxn = limit ? b[u] : 9;
    int ret = 0, cur;
    
    for(int i=0; i<=maxn; i++) {
        cur = f - i*(1<<u-1);
        if(cur > 0) {
            ret += dfs(u-1, cur, limit && i==maxn);
        } else if(cur == 0) {
            ret += 1;
        }
    }
    
    if(!limit)    dp[u][f] = ret;
    return ret;
}

int f(int n, int a)
{
    int lenb=0;
    memset(b, 0, sizeof(b));
    while(n) {
        b[++lenb] = n%10;
        n /= 10;
    }
    return dfs(lenb, a, 1);
}

int main ()
{
    num[0] = 1;
    for(int i=1; i<10; i++) {
        num[i] = num[i-1] * 10;
    }
    
    int T, A, B;
    scanf("%d", &T);
    memset(dp, -1, sizeof(dp));
    for(int kase=1; kase<=T; kase++) {
        scanf("%d%d", &A, &B);
        int base = 1, F=0;
        while(A) {
            F += base * (A % 10);
            
            base <<= 1;
            A /= 10;
        }
        printf("Case #%d: %d\n", kase, f(B, F));
    }
    return 0;
}

 

posted on 2016-04-13 22:48  SuperChan  阅读(142)  评论(0编辑  收藏  举报

导航