• usaco 3.2 Stringsobits 数位dp


    Stringsobits
    Kim Schrijvers

    Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either 0 or 1.

    This set of strings is interesting because it is ordered and contains all possible strings of length N that have L (1 <= L <= N) or fewer bits that are `1'.

    Your task is to read a number I (1 <= I <= sizeof(S)) from the input and print the Ith element of the ordered set for N bits with no more than L bits that are `1'.

    PROGRAM NAME: kimbits

    INPUT FORMAT

    A single line with three space separated integers: N, L, and I.

    SAMPLE INPUT (file kimbits.in)

    5 3 19
    

    OUTPUT FORMAT

    A single line containing the integer that represents the Ith element from the order set, as described.

    SAMPLE OUTPUT (file kimbits.out)

    10011
    

     求二进制长度为N(可包括前导0)的1的个数不超过L的第I个数。

    反着想,设第I个数为m,数位dp可以很轻松地求出[0,m]的符合条件(二进制长度为N(可包括前导0)的1的个数)的数的个数k,显然m是第k个数。

    因此直接二分判断就可以了。

    /*
    ID: xidian5601
    PROG: kimbits
    LANG: C++
    */
    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    ll N,L,I;
    ll f[40][40];
    int num[40],len;
    
    ll dfs(int i,int cnt,int e)
    {
        if(i==-1) return cnt<=L;
        if(!e&&~f[i][cnt]) return f[i][cnt];
        ll res=0;
        int u=e?num[i]:1;
        REP(d,0,u){
            if(cnt+d<=L) res+=dfs(i-1,cnt+d,e&&d==u);
        }
        return e?res:f[i][cnt]=res;
    }
    
    ll F(ll n)
    {
        len=0;
        while(n){
            num[len++]=n%2;
            n/=2;
        }
        return dfs(len-1,0,1);
    }
    
    int cnt(ll n)
    {
        int res=0;
        while(n){
            res+=n%2;
            n/=2;
        }
        return res;
    }
    
    ll bin(ll l,ll r,ll kth)
    {
        while(l<=r){
            ll m=(l+r)>>1;
            ll t=F(m),c=cnt(m);
            if(c<=L&&t==kth) return m;
            if(t==kth&&c>L) r=m-1;
            else if(t>kth) r=m-1;
            else l=m+1;
        }
    }
    
    void Print(ll n)
    {
        len=0;
        while(n){
            num[++len]=n%2;
            n/=2;
        }
        REP(i,len+1,N) printf("0");
        for(int i=len;i>=1;i--) printf("%d",num[i]);puts("");
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        freopen("kimbits.in","r",stdin);
        freopen("kimbits.out","w",stdout);
        while(cin>>N>>L>>I){
            memset(f,-1,sizeof(f));
            Print(bin(0,(1LL<<N)-1,I));
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    DHCP服务搭建
    JumpServer跳板机
    PXE
    DNS
    MySQL
    企业级LNMP分离式部署
    MHA-Atlas-MySQL高可用集群2
    MHA-Atlas-MySQL高可用集群
    备份全网服务器数据
    FTP
  • 原文地址:https://www.cnblogs.com/--560/p/5186835.html
Copyright © 2020-2023  润新知