zoukankan      html  css  js  c++  java
  • Hdu 4734-F(x) 数位dp

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=4734

    F(x)

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


    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
    3 0 100 1 10 5 100
     
    Sample Output
    Case #1: 1 Case #2: 2 Case #3: 13
     
    Source
     
    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:  5664 5663 5662 5661 5660 
     
    题意:对于一个n位的十进制数x(AnAn-1……A1),我们定义它的权重为:
      F(x)=An*2n-1+An-1*2n-2+……+A1*20
      现在,给你两个十进制数A和B,请计算出在闭区间[0, B]之中,有多少个数x的权重不大于A的权重,即F(x)<=F(A)。
    题解:
    数位dp
    预处理出A的权重。f[i][j]为到第i位比j小的方案数。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int DP[12][4616],digit[12];
     4 int read()
     5 {
     6     int s=0,fh=1;char ch=getchar();
     7     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     8     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     9     return s*fh;
    10 }
    11 int GetFA(int k)
    12 {
    13     int sum=0,tmp=1;
    14     while(k!=0)
    15     {
    16         sum+=(k%10)*tmp;k/=10;
    17         tmp*=2;
    18     }
    19     return sum;
    20 }
    21 int Dfs(int len,int FA,int limit)
    22 {
    23     if(FA<0)return 0;
    24     if(len<=0)return 1;
    25     if(limit==0&&DP[len][FA]!=-1)return DP[len][FA];
    26     int end=limit?digit[len]:9,ret=0,i;
    27     for(i=0;i<=end;i++)ret+=Dfs(len-1,FA-i*(1<<(len-1)),limit&&(i==end));
    28     if(limit==0)DP[len][FA]=ret;
    29     return ret;
    30 }
    31 int Calc(int FA,int B)
    32 {
    33     int len=0;
    34     memset(digit,0,sizeof(digit));
    35     while(B!=0){digit[++len]=B%10;B/=10;}
    36     return Dfs(len,FA,1);
    37 }
    38 int main()
    39 {
    40     int case1=0,A,B,FA,T;
    41     T=read();
    42     memset(DP,-1,sizeof(DP));
    43     while(T--)
    44     {
    45         A=read();B=read();
    46         FA=GetFA(A);
    47         //memset(DP,-1,sizeof(DP));
    48         printf("Case #%d: %d
    ",++case1,Calc(FA,B));
    49     }
    50     fclose(stdin);
    51     fclose(stdout);
    52     return 0;
    53 }
  • 相关阅读:
    spring 心跳更新
    eclipse 控制台输出太多,显示不完整
    String
    iOS 开发之如何生成SDK(2)-----生成framework
    如何防止自己的APP被Hook
    JavaAPI类
    Java面向对象三大特性—封装
    Java类与对象
    Java基础易错点1
    Java数组反转及二维数组
  • 原文地址:https://www.cnblogs.com/Var123/p/5385158.html
Copyright © 2011-2022 走看看