• bzoj3917: [Baltic2014]sequence


    Description

     序列A由从N开始的连续K个数按顺序构成,现在将A中的每个数只保留某一个数码,记为序列B,给定K和B,求可能的最小的N

    Input

    第一行一个数K,第二行K个数B_i

    Output

    输出一个数N

    当确定了N的个位时,可以确定这连续的K个数的个位,这是得到子问题求N/10的值,B数组(压位表示子问题中哪些位必须出现)对应更新为大约K/10的长度,于是可以递归处理,当K=1时贪心确定所需的最高位

    当K=2时若选择个位为9则递归下去K仍为2,要特判剪枝一下

    递归到K=1时,若答案有必须存在的前导0则要特判在前面补位

    #include<cstdio>
    typedef long long i64;
    int _(){
        int x=0,c=getchar();
        while(c<48)c=getchar();
        while(c>47)x=x*10+c-48,c=getchar();
        return x;
    }
    int n,v[100007],d[500007];
    i64 dfs(int*d0,int n,bool _9,bool _0){
        bool dd=0;
        for(int i=0;i<n;++i)if(d0[i]){dd=1;break;}
        if(!dd)return _0;
        if(n==1){
            int x=*d0;
            if(x==1)x=3;
            i64 v=0;
            for(int i=1;i<10;++i)if(x>>i&1){
                v=i;
                x^=1<<i;
                break;
            }
            for(int i=0;i<10;++i)if(x>>i&1)v=v*10+i;
            return v;
        }
        i64 v0=1ll<<60;
        int*d1=d0+n;
        for(int a=0;a<10;++a){
            if(a==9&&!_9)break;
            int n1=0,x=a,s=0;
            for(int b=0;b<n;++b){
                s|=d0[b]&~(1<<x);
                if(++x==10){
                    x=0;
                    d1[n1++]=s;
                    s=0;
                }
            }
            if(x)d1[n1++]=s;
            i64 v1=dfs(d1,n1,a!=9||n>2,!a&&(_0||(1&*d0)))*10+a;
            if(v1<v0)v0=v1;
        }
        return v0;
    }
    int main(){
        n=_();
        for(int i=0;i<n;++i)d[i]=1<<(v[i]=_());
        printf("%lld",dfs(d,n,1,1));
        return 0;
    }
  • 相关阅读:
    前端+php实现概率抽奖
    rem.js的用法及在浏览器端的适配
    python 使用记录及问题
    python 工具链 虚拟环境和包管理工具 pipenv
    python 工具链 多版本管理工具 pyenv
    python 工具链 包管理工具 pip
    ansible 使用记录
    mongodb connection refused because too many open connections: 819
    wordpress 常用操作
    服务器硬件测试
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6063221.html
Copyright © 2020-2023  润新知