题意: 构造一个序列(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;
}
所有评论(0)