题意: 构造一个序列(1-n),使LIS和LDS的和最小

分析: 根据Dilworth'o theorem,最长上升子序列的个数等于最长不升子序列的长度

          则LIS + LDS = 最长上升子序列的个数 + 最长上升子序列的长度(因为1-n)

    

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
/*


*/
int N;
int ans[100500];
int main() {
    scanf("%d",&N);
    //len表示最长子序列的长度 
    int len = N;
    int arrs = 1;
    int sum = 100000000;
    int mid = sqrt(N);
    for (int i = 1;i <= mid;i++) {
        if (N % i == 0) {
            if (i + N / i < sum) {
                sum = i + N / i;
                len = i;
            }
        }else {
            if (i + N / i + 1 < sum) {
                sum = i + N / i + 1;
                len = i;
            }
        }
//        printf("sum,len: %d %d\n",sum,len);
    }
    int flag = 1;
    if (N % len == 0) {
        //恰好分为arrs组 
        arrs = N / len;
        for (int i = 0;i < arrs;i++) {
            for (int j = len;j >= 1;j--) {
                if (flag) {
                    printf("%d",i * len + j);
                    flag = 0;
                }else {
                    printf(" %d",i * len + j);
                }
            }
        }
    }else {
        arrs = N / len + 1;
        int count0 = 0;
        for (int i = 0;i < arrs - 1;i++) {
            for (int j = len;j >= 1;j--) {
                if (flag) {
                    printf("%d",i * len + j);
                    flag = 0;
                }else {
                    printf(" %d",i * len + j);
                }
                count0++;
            }
        }
        for (int i = N;i > count0;i--) {
            printf(" %d",i);
        }
    }
    printf("\n");
    
    return 0;
}

 

         

 

转载于:https://www.cnblogs.com/akira123/p/9735962.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐