hdu 4734 F(x)

来源:互联网 发布:交换机禁止mac地址 编辑:程序博客网 时间:2024/05/21 19:33

F(x)

Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2781    Accepted Submission(s): 1029


Problem Description
For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 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 < 109)
 

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
30 1001 105 100
 

Sample Output
Case #1: 1Case #2: 2Case #3: 13
 

Source
2013 ACM/ICPC Asia Regional Chengdu Online
 


数位DP;dp[pos][sum]:当前位数为pos时,最大值为f(a)时,当前位还剩下sum可以用。

#include<stdio.h>#include<string.h>#include<math.h>int dp[11][5120];int dight[11],num[11];int a,b,m;int dfs(int pos,int sum,int flag){  if(pos==-1)        if(sum>=0)return 1;        else return 0;        if(sum<0)return 0;        if(!flag&&dp[pos][sum]!=-1)return dp[pos][sum];        int i,ans=0,u=flag?dight[pos]:9;        for(i=0;i<=u;i++)            ans=ans+dfs(pos-1,sum-i*num[pos],flag&&i==u);            if(!flag)dp[pos][sum]=ans;            return ans;}int fun(int n){    int len=0;    while(n)    {        dight[len++]=n%10;        n=n/10;    }    dfs(len-1,m,1);}int main(){    int t,i,x;    scanf("%d",&t);    for(i=0;i<11;i++)        num[i]=pow(2,i);        memset(dp,-1,sizeof(dp));   for(i=1;i<=t;i++)    {x=1;m=0;        scanf("%d %d",&a,&b);        while(a)        {           m=m+a%10*x;           x=x*2;           a=a/10;        }        printf("Case #%d: %d\n",i,fun(b));    }    return 0;}


0 0
原创粉丝点击