• 序列 [构造题]


    序列


    color{red}{正解部分}

    首先 最多有一个数字同时出现在 最长上升子序列最长下降子序列 中, 所以若 A+B>N+1A+B > N+1, 说明 无解 .

    然后考虑怎么构造, 将 {1,2,3...N}{1,2,3...N} 分成若干个大小为 BB 的块(可能会剩下一个小块), 总共有 a=NBa = lceil frac{N}{B} ceil 个块,

    最长上升子序列 的长度至少为 aa, 若 A<aA < a, 说明 无解 .
    否则可以在 内反转元素, 每反转一次 最长上升子序列 的长度会增加 11, 最长下降子序列 的长度不变 .

    按上述方法构造即可 .


    color{red}{实现部分}

    将剩余部分放在前面

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 1e5 + 10;
    
    int N;
    int A;
    int B;
    
    bool used[maxn];
    
    void Work(){
            N = read(), A = read(), B = read();
            for(reg int i = 1; i <= N; i ++) used[i] = 0;
            int left = N / B;
            if(N % B) left ++;
            if(A+B > N+1 || A < left){ printf("No
    "); return ; }
            printf("Yes
    ");
            int base = N % B;      
            for(reg int i = 1; i <= A-left; i ++){
                    used[i] = 1, printf("%d ", i);
                    if((i - base) % B == 0) A ++;
            }
            int t = N%B;
            while(t <= N){
                    int t2 = std::max(1, t - B + 1), tmp = t;
                    while(tmp >= t2){
                            if(!used[tmp]) printf("%d ", tmp);
                            tmp --;
                    }
                    t += B;
            }
            printf("
    ");
            /*
            if(t >= N + 1){
                    for(reg int j = 0 ; j < t; j ++) printf("%d ", ++ cur);
            }
            for(reg int i = 1; i <= B; i ++) printf("%d ", i-1);
            */
    }
    
    int main(){
            int T = read();
            while(T --) Work();
            return 0;
    }
    

    将剩余部分放在后面

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 1e6 + 10;
    
    int N;
    int A;
    int B;
    
    bool used[maxn];
    
    void Work(){
            N = read(), A = read(), B = read();
            for(reg int i = 1; i <= N; i ++) used[i] = 0;
            int left = N / B;
            if(N % B) left ++;
            if(A+B > N+1 || A < left){ printf("No
    "); return ; }
            printf("Yes
    ");
            for(reg int i = 1; i <= A-left; i ++){
                    used[i] = 1, printf("%d ", i);
                    if(i % B == 0) A ++;
            }
            int t = B;
            while(t <= N){
                    int t2 = t - B + 1, tmp = t;
                    while(tmp >= t2){
                            if(!used[tmp]) printf("%d ", tmp);
                            tmp --;
                    }
                    t += B;
            } 
            for(reg int i = N; i >= N-(N%B)+1; i --) if(!used[i]) printf("%d ", i);
            printf("
    ");
    }
    
    int main(){
            freopen("seq.in", "r", stdin);
            freopen("seq.out", "w", stdout);
            int T = read();
            while(T --) Work();
            return 0;
    }
    
  • 相关阅读:
    状态模式
    maven-war-plugin 插件 web.xml 缺失时忽略
    Java远程方法协议(JRMP)
    Java Singleton的3种实现方式
    浅谈分布式消息技术 Kafka
    浅谈分布式事务
    J2EE开发时的包命名规则,养成良好的开发习惯
    使用Dom4j创建xml文档
    Java HttpClient Basic Credential 认证
    Spring MVC的Post请求参数中文乱码的原因&处理
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822452.html
Copyright © 2020-2023  润新知