持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情
【2022牛客多校-2】G Link with Monotonic Subsequence
题目链接
题目
First, let's review some definitions. Feel free to skip this part if you are familiar with them.
A sequence is an increasing (decreasing) subsequence of a sequence if can be obtained from by deletion of several (possibly, zero or all) elements and all elements are in increasing (decreasing) order from the beginning to the end.
A permutation is an array consisting of distinct integers from to in arbitrary order. For example, is a permutation, but is not a permutation ( appears twice in the array) and is also not a permutation ( but there is in the array).
The problem starts from here.
Link has an array. He is currently learning the longest increasing subsequence algorithm. So he comes up with the following question.
Let the value of a permutation be , where is the length of the longest increasing subsequence of ppp and lds(p){\rm lds}(p)lds(p) is the length of the longest decreasing subsequence of . For all permutations of length , which one has the minimum value?
题目大意
构造一个排列,使其 最小。
思路
排列权值的最小值为 ,即对于一个长度为n的全排列, 的最小值是 的上取整。证明如下:
记排列中的第 个元素为 ,对于排列中的每个元素,我们记一个二元组 ,其中 表示以第 i 个数结尾的最长上升子序列长度, 表示以第 i 个数结尾的最长下降子序列长度。
对于每个排列生成的所有二元组中的任意两个二元组,下标分别记为 且 :
- 若 ,则 ;
- 若 ,则 ;
- 若 ,则不可能。(a为排列)
因此,对于某个排列生成的所有二元组,其必定是两两不同的。
得证所有二元组中的最大值至少为 。
由上述结论,我们可以将整个序列分为若干组,每组 块,将每组内元素倒序输出( ),各组正序输出( )即可。
代码
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
int T,n;
int main()
{
for (scanf("%d",&T);T--;)
{
scanf("%d",&n);
int k=sqrt(n),i;
if (k*k!=n) k++;
for (i=0;i<=n;i+=k)
for (int j=min(n,i+k);j>i;--j) printf("%d ",j);
printf("\n");
}
return 0;
}