• URAL


    题目链接:H - Binary Lexicographic Sequence

    题意:

    Consider all the sequences with length (0 <  N < 44), containing only the elements 0 and 1, and no two ones are adjacent (110 is not a valid sequence of length 3, 0101 is a valid sequence of length 4). Write a program which finds the sequence, which is on K-th place (0 <  K < 10 9) in the lexicographically sorted in ascending order collection of the described sequences.

    Input

    The first line of input contains two positive integers N and K.

    Output

    Write the found sequence or −1 if the number K is larger then the number of valid sequences.
    inputoutput
    3 1
    
    000

    题意就是求长度为3的第k大的01串,串的要求1不可以相邻

    题解:我们二分答案,把答案转化为二进制,怎么判断呢,用数位dp求出比当前串要小的合法个数,我们先用

    dp[pos][0]表示长度为pos第1个为0的串的个数dp[pos][1]开头为1的个数
    转移方程看代码。
    #include<bits/stdc++.h>
    #include<set>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #define pb push_back
    #define ll long long
    #define PI 3.14159265
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define eps 1e-7
    typedef unsigned long long ull;
    const int mod=1e9+9;
    const int inf=0x3f3f3f3f;
    const int maxn=1e5+5;
    const int root=1e6+7;
    using namespace std;
    ll t,n,m,k,len;
    int a[50];
    ll dp[50][2];//dp[pos][0]表示长度为pos第1个为0的串的个数dp[pos][1]开头为1的个数
    void init()
    {
        dp[1][0]=1;dp[1][1]=1;
        dp[2][0]=2;dp[2][1]=1;
        for(int i=3;i<=44;i++)
        {
            dp[i][0]=dp[i-1][0]+dp[i-1][1];
            dp[i][1]=dp[i-1][0];
        }
    }
    int slove(ll x)
    {
        int t=1;
        while(x)
        {
            if(x%2)a[t]=1;
            else a[t]=0;
            x/=2;
            t++;
        }
        return t;
    }
    ll dfs(ll pos,bool lim,bool pre)//求小于等于x的合法串个数
    {
        if(pos==0)
        {
            return 1;
        }
        ll ans=0;
        if(!lim)
        {
            if(!pre)
            {
                return dp[pos][0]+dp[pos][1];
            }
            else
            {
                return dp[pos][0];
            }
        }
        else
        {
            if(a[pos]==0)
            {
                return dfs(pos-1,true,false);
            }
            else
            {
                if(!pre)ans+=dfs(pos-1,true,true);
                ans+=dfs(pos-1,false,false);
                return ans;
            }
        }
    
    }
    bool judge(ll x)
    {
        memset(a,0,sizeof(a));
        len=slove(x);
        ll sum=dfs(n,1,0);
        return sum>=k;
    }
    int main()
    {
        init();
        while(~scanf("%lld %lld",&n,&k))
        {
            ll l=0;
            ll r=(1ll<<n)-1;//这里要用ll不然位运算会溢出
            while(l<=r)
            {
                ll mid=(l+r)>>1;
                if(judge(mid))r=mid-1;
                else l=mid+1;
            }
            memset(a,0,sizeof(a));
            if(k>dp[n][0]+dp[n][1]){
                puts("-1");
                continue;
            }
            len=slove(l);
            for(int i=n;i>=1;i--)
            {
                printf("%d",a[i]);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Java和.NET(C#)的开发用到的技术对比总结
    Sql 调优总结
    10分钟开发 GPS 应用,了解一下
    windows 命令行操作 Mysql 数据库
    【C# 复习总结】类、继承和接口
    【C#复习总结】探究各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字
    【C#复习总结】析构函数
    【C#复习总结】垃圾回收机制(GC)2
    【C#复习总结】垃圾回收机制(GC)1
    设计原则总结
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/8423760.html
Copyright © 2020-2023  润新知