zoukankan      html  css  js  c++  java
  • HDU 4734

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

    Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

    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

    题意:

    给出T组数据,对于每组数据有A,B;

    假设数字x有n位:(AnAn-1An-2 ... A2A1),那么定义数字x的权重计算函数为F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1;

    现在要求[0,B]之间,有多少个数字的权重不大于F(A).

    题解:

    刚开始一眼看到这题,算了一下 F(999999999) = 4599,也不是很大,

    就感觉挺简单的,想着dp[pos][weight]不就完事了,weight记录从len到pos位上数字累计的权重;

    写出来交了一发,TLE,感觉就有点奇怪,翻了翻网上的题解,说是不能是dp[pos][weight],要是dp[pos][F(A) - weight]才行;

    也就是说,新定义dp[pos][comp],comp代表剩下的从第pos位到第1位,累加起来的权重,不能超过comp;

    这是为什么呢?原因其实很简单:

      我们定义dp[pos][weight]的话,显然我们这T组数据……

      每组数据只要B有变化,由于weight是从最高位往下累加权重,它跟B有密切关系(B的长度len即为最高位),那么dp数组就要重新memset(dp,-1,sizeof(dp)),这样才不会出错;

    那么我们如果是dp[pos][comp]呢,comp代表从第1位到第pos位最多还能累加起多少权重,那么它就和B没什么关系,我们就不需要在输入每组数据后都重新将DP数组全部重置为-1。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int dig[11];
    int dp[11][5000];
    int A,B;
    int pow2[11];
    
    int F(int x)
    {
        int cnt=0;
        int ret=0;
        while(x)
        {
            ret+=(x%10)<<cnt;
            x/=10;
            cnt++;
        }
        return ret;
    }
    
    int dfs(int pos,int comp,bool limit)
    {
        if(pos==0) return comp>=0;
        if(!limit && dp[pos][comp]!=-1) return dp[pos][comp];
    
        int up=limit?dig[pos]:9;
        int ans=0;
        for(int i=0;i<=up;i++)
        {
            int new_comp=comp-i*pow2[pos-1];
            if(new_comp<0) continue;
            ans+=dfs(pos-1,new_comp,limit && i==up);
        }
    
        if(!limit) dp[pos][comp]=ans;
        return ans;
    }
    int solve(int x)
    {
        int len=0;
        while(x)
        {
            dig[++len]=x%10;
            x/=10;
        }
        return dfs(len,F(A),1);
    }
    
    int main()
    {
        pow2[0]=1;
        for(int i=1;i<=10;i++) pow2[i]=pow2[i-1]*2;
    
        int t;
        scanf("%d",&t);
        memset(dp,-1,sizeof(dp));
        for(int kase=1;kase<=t;kase++)
        {
            scanf("%d%d",&A,&B);
            printf("Case #%d: %d
    ",kase,solve(B));
        }
    }
  • 相关阅读:
    ThreadLocal Thread ThreadLocalMap 之间的关系
    组合注解(Annotation)
    Halo 开源项目使用jsdelivr进行CDN加速.
    如何正确认知和提升自己的“格局”“视野”“高度”?
    格局如何提高?站在未来看今天。
    Cookie 的技术学习笔记
    JVM垃圾收集器与内存分配策略
    java内存区域与内存溢出异常
    JAVA中的BIO,NIO与多路复用(select,poll,epoll)
    Hexo yilia主题搭建自己的github个人博客(一)
  • 原文地址:https://www.cnblogs.com/dilthey/p/8545485.html
Copyright © 2011-2022 走看看