zoukankan      html  css  js  c++  java
  • [HDU 4734]F(x)[数位DP]

    题意:

    将一个十进制数

    n = dn dn-1 ... d0

    视为二进制. 即

    F(n) = dn*2^n + ... + d0*2^0.

    给出A, B. 求0 ... B之间, 该值不大于F(A)的数的个数.

    思路:

    数位DP.

    数位DP的优点在于, 你不需要直到这个答案是怎么来的, 只需要知道递推式. 这个答案的生成过程就在递推的过程中.

    dp [ i ] [ j ] 表示 i 位的数{ x } 中 F ( x ) 小于 j 的数的个数.

    #include<cstdio>
    #include<cstring>
    #define maxn 16
    int dp[maxn][111111];
    int d[maxn];
    int n;
    long long tt;
    long long  dfs(int len ,int pre ,bool fp)
    {
        if(pre<0)return 0;//说明上一层枚举的数超过了上限,没有可用的情况
        if(!len)return 1;//说明上一层是个位.那么只需要把各个数累加起来就可以
        if(!fp&&dp[len][pre]!=-1)return dp[len][pre];//记忆化搜索
        int fpmax=fp?d[len]:9;//取该位取值的最大值
        int ret=0;
        for(int i=0;i<=fpmax;i++){//从最大长度向下,每一个长度的所有取值都要遍历到,
            //一旦该位的取值不是紧贴最大值,fp就false.
            ret+= dfs(len-1,pre-i*(1<<(len-1)),fp&&i==fpmax);
        }
        if(!fp)dp[len][pre]=ret;//记录结果
        return ret;
    }
    long long  calc(long long a)
    {
        int len=0;
        memset(d,0,sizeof(d));
        while(a){
            d[++len]=a%10;
            a/=10;
        }
        return dfs(len,tt,true);
    }
    int get(int x)
    {
        int tmp=1;
        int ans=0;
        while(x){
            ans+=(x%10)*tmp;
            x/=10;
            tmp<<=1;
        }
        return ans;
    }
    int main()
    {
        long long  a,b;
        int nc;
        scanf("%d",&nc);
        int d=1;
        memset(dp,-1,sizeof(dp));
        while(nc--){
            scanf("%I64d%I64d",&a,&b);
            tt=get(a);
            printf("Case #%d: %I64d
    ",d++,calc(b));
        }
        return 0;
    }
    


  • 相关阅读:
    微信小程序登录
    cURL error 60: SSL certificate problem: unable to get local issuer certificate 报错解决
    MyBatis学习之一----基础了解
    web工程和java工程的区别
    StringUtils的实用功能
    SpringMVC-----部分功能学习
    SpringMVC之国际化
    SpringMVC
    web.xml配置详解
    Hibernate学习-----遇到的相关问题
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3322829.html
Copyright © 2011-2022 走看看