zoukankan      html  css  js  c++  java
  • F(x)

    题目链接: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): 8015    Accepted Submission(s): 3141


    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
     
    题目大意:t组测试样例,输入n,m,按上述方法计算出f(n),然后问你[0,m]之中有多少个数按上述方法求出来的值小于等于f(n)
    个人思路:其实这道题就算加了权值的数位dp了,每位数按着方法乘以权值就行,然后还有一个优化,不然会超时。。。这道题按照一般的思路,就算直接求了,从最高位开始,一直往下
    求,如果在这期间已经大于了就直接退出来,但是这里有一个优化dp[pos][sum],这里的sum 不是当前的前缀和(加了权值的)而是当前位离答案还差<=sum的数的个数,为什么是这样呢?
    如果sum值是前缀和的话,因为目标是不一样的(也就是f(n)),所以即使计算出这个也没啥用,大概思路就算这个了
    看代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stdio.h>
    #include<string.h>
    #include<cmath>
    #include<math.h>
    #include<algorithm>
    #include<set>
    #include<queue>
    #include<map>
    typedef long long ll;
    using namespace std;
    const ll mod=1e9+7;
    const int maxn=1e8+10;
    const int maxk=100+10;
    const int maxx=1e4+10;
    const ll maxa=43200;
    #define INF 0x3f3f3f3f3f3f
    int a[15];
    int dp[15][10000];
    int edge;
    int dfs(int pos,int sum,int limit)
    {
        if(pos==-1)
            return sum<=edge?1:0;
         //  return sum<=edge;
         if(sum>edge)
            return 0;
        if(!limit&&dp[pos][edge-sum]!=-1) return dp[pos][edge-sum];
    
        int up=limit?a[pos]:9;
        int ans=0;
        for(int i=0;i<=up;i++)
        {
             ans+=dfs(pos-1,sum+i*(1<<pos),limit&&i==a[pos]);
        }
        if(!limit) dp[pos][edge-sum]=ans;
        return ans;
    }
    ll f(ll n)
    {
        ll t=1,ans=0;
        while(n)
        {
            ans+=n%10*t;
            n=n/10;
            t*=2;
        }
        return ans;
    }
    ll solve(ll n)
    {
        int pos=0;
        while(n)
        {
            a[pos++]=n%10;
            n=n/10;
        }
        return dfs(pos-1,0,1);
    }
    int main()
    {
        int t;
        cin>>t;
        memset(dp,-1,sizeof(dp));
        for(int i=1;i<=t;i++)
        {
            ll n,m;
            cin>>n>>m;
            edge=f(n);
           // cout<<edge<<endl;
            printf("Case #%d: %I64d
    ",i,solve(m));
        }
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/caijiaming/p/9361986.html
Copyright © 2011-2022 走看看