zoukankan      html  css  js  c++  java
  • HDOJ 3943 Kth Nya Number(数位DP)

    题意:求区间(P , Q]中第K个恰含x个4和y个7的数。P,Q<2^63

    分析:以前看到的数位DP的题都是求某个区间内满足给定条件的数的个数,看到这题我们一下可能没什么想法,也可能想到先求区间内的个数,然后二分答案,初看起来可以,但仔细想想就会发现有问题,因为即使知道(P , Q]内恰好有K个,你还是不知道第K个是哪个,所以二分貌似做不了。后来搜了下别人的解法,看过之后才恍然大悟,求解的过程非常巧妙,简而言之就是从高到低依次确定各个位的数字。不解释太多,看代码就明白了……

    View Code
    #include <stdio.h>
    #include <string.h>
    #define N 23
    typedef __int64 LL;
    int X,Y,digit[N];
    LL P,Q,K,dp[N][N][N];
    LL dfs(int pos,int x,int y,int f)
    {
        if(pos==-1) return (x==X&&y==Y)?1:0;
        if(!f&&dp[pos][x][y]!=-1)   return dp[pos][x][y];
        LL ret=0;
        int max=f?digit[pos]:9;
        for(int i=0;i<=max;i++)
        {
            ret+=dfs(pos-1,x+(i==4),y+(i==7),f&&i==max);
        }
        if(!f)  dp[pos][x][y]=ret;
        return ret;
    }
    LL cal(LL x)
    {
        int pos=0;
        while(x)
        {
            digit[pos++]=x%10;
            x/=10;
        }
        return dfs(pos-1,0,0,1);
    }
    void makeans(int pos,int x,int y,int f,LL k,LL &ans)
    {
        if(pos==-1) return;
        LL ret=0;
        int i,max=f?digit[pos]:9;
        for(i=0;i<=max;i++)
        {
            if(ret+dfs(pos-1,x+(i==4),y+(i==7),f&&i==max)>=k)  break;
            ret+=dfs(pos-1,x+(i==4),y+(i==7),f&&i==max);
        }
        ans=ans*10+i;
        makeans(pos-1,x+(i==4),y+(i==7),f&&i==max,k-ret,ans);
    }
    void solve(LL x,LL k)
    {
        k+=cal(P);
        int pos=0;
        while(x)
        {
            digit[pos++]=x%10;
            x/=10;
        }
        LL ans=0;
        makeans(pos-1,0,0,1,k,ans);
        printf("%I64d\n",ans);
    }
    int main()
    {
        int t,n,ca=0;
        scanf("%d",&t);
        while(t--)
        {
            memset(dp,-1,sizeof(dp));
            printf("Case #%d:\n",++ca);
            scanf("%I64d%I64d%d%d",&P,&Q,&X,&Y);
            scanf("%d",&n);
            while(n--)
            {
                scanf("%I64d",&K);
                if(cal(Q)-cal(P)<K) puts("Nya!");
                else    solve(Q,K);
            }
        }
        return 0;
    }
  • 相关阅读:
    linux中apt-get使用
    部署ceph
    cinder存储服务
    ceph简介
    Horizon Web管理界面
    neutron网络服务2
    neutron网络服务
    nova计算服务
    cinder存储服务
    keystone身份认证服务
  • 原文地址:https://www.cnblogs.com/algorithms/p/2685335.html
Copyright © 2011-2022 走看看