zoukankan      html  css  js  c++  java
  • hdu4734 F(x)(数位dp)

    题目传送门

    F(x)

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


    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
     
    题意:定义F(x),求在[0,m]中F[x]小于F(n)的数的个数
    题解:数位dp
    代码:
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long long ll;
    typedef pair<int,int> PII;
    #define mod 1000000007
    #define pb push_back
    #define mp make_pair
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    //head
    int T;
    int n,m;
    int bit[10];
    int dp[10][4600];
    int F(int x)
    {
        int cnt=0;
        int len=0;
        while(x)
        {
            cnt+=(x%10)*(1<<len);
            x/=10;
            len++;
        }
        return cnt;
    }
    int dfs(int pos,int sta,bool limit)
    {
        if(pos==-1) return sta>=0;
        if(sta<0) return 0;
        if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
        int ans=0;
        int up=limit?bit[pos]:9;
        for(int i=0;i<=up;i++)
            ans+=dfs(pos-1,sta-i*(1<<pos),limit&&i==up);
        if(!limit) dp[pos][sta]=ans;
        return ans;
    }
    int calc(int x)
    {
        int len=0;
        while(x)
        {
            bit[len++]=x%10;
            x/=10;
        }
        return dfs(len-1,F(n),true);
    }
    int main()
    {
        scanf("%d",&T);
        int ncase=0;
        memset(dp,-1,sizeof(dp));
        while(T--)
        {
            scanf("%d %d",&n,&m);
            printf("Case #%d: ",++ncase);
            printf("%d
    ",calc(m));
        }
        return 0;
    }
  • 相关阅读:
    JAVA课程作业01
    《大道至简》第二章读后感
    《大道至简》第一章读后感
    制作Linux镜像,将腾讯云服务器系统制成镜像
    postman数据驱动
    Navicat Premium 连接Oracle数据库报错 instant Client LIght : unsupported server charcter ser ZHS16GBK
    查看python位数
    AutoItLibrary安装过程中遇到的坑
    hyrobot使用
    有这样一道智力题:“某商店规定:三个空汽水瓶
  • 原文地址:https://www.cnblogs.com/zhgyki/p/9758010.html
Copyright © 2011-2022 走看看