• 序列(seq)


    【from new_dtoj 3965: 序列(seq)】
    题目描述
    给定 N,A,B,构造一个长度为 N 的排列,使得:
    排列长度为 N;
    最长上升子序列长度为 A;
    最长下降子序列长度为 B。
    输入
    第一行一个整数 T (1≤T≤10), 表示数据组数.
    接下来 T 行,每行三个正整数 N、A、B。
    输出
    对每组数据:
    如果有解,输出两行,第一行一个字符串 Yes,接下来一行 N 个整数,表示排列。
    否则, 输出一行一个字符串 No。
    样例输入
    3
    4 2 2
    4 4 1
    4 3 3
    样例输出
    Yes
    3 4 1 2
    Yes
    1 2 3 4
    No
    提示
    数据范围和子任务
    对于全部的测试数据,保证T≤10,N≤105,∑N≤2×105
    子任务 1(20 分):N≤5 .
    子任务 2(30 分):每组数据均满足 N=A×B .
    子任务 3(20 分):B≤2 .
    子任务 4(30 分):无特殊限制
    题解如下:
    显然当A+B>n+1时,无解
    由于子任务2联想到可以构造出1条长度为B的下降序列,并且这一条序列上的每个点都是一条长度至多为A的上升序列。故当A*B<n时,也是无解的情况,剩下的情况就可以按照上述方法构造,即3216549873_{2_1}^{{6_{5_4}}^{9_{8_7}}}321654987类似的构造法
    代码如下:

    #include <cstdio>
    int n,a,b,s[100005],t,T,k,c;
    int main(){
        for (scanf("%d",&T);T--;){
            scanf("%d%d%d",&n,&a,&b);
            if (a*b<n || a+b>n+1){puts("No");continue;}
            puts("Yes");t=0;k=b;c=n;
            for (int i=1;i<=b;i++){
                if (n-a>=b-i) n-=a;else break;k--;
                for (int j=n+1;j<=n+a;j++) s[++t]=j;
            }
            if (n) for (int i=k;i<=n;i++) s[++t]=i;
            for (int i=k-1;i>0;i--) s[++t]=i;
            for (int i=1;i<=c;i++) printf("%d%c",s[i],i<c?' ':'
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    linux整理
    C++ 11 多线程--线程管理
    VS2013 配置全局 VC++目录
    visual studio运行时库MT、MTd、MD、MDd的研究
    C++(vs)多线程调试 (转)
    VS工程和Qt工程转换
    Qt 读写XML文件
    win32开发中多字节(ANSI)和宽字符(UNICODE)字符串处理函数参考
    QMenu----QT鼠标右键弹出菜单
    C++ 单例模式析构函数的运用,析构函数的线程安全
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/10544733.html
Copyright © 2020-2023  润新知