题目大意:
给一个数列长度n,要求输出一个最长上升序列长度和最长下降数列长度和最小的数列。
解题思路:
这个我是靠观察答案蒙出来的。具体算法的证明我也不懂。。。。答案将数列分段,每一段都是连续上升数列,这样LIS的长度就是每一段的长度,LDS的长度就是它可以分为几段。分段的依据就是n的根号,例如小于9大于3的每段长度为2(LIS长度),大于9小于16的每段长度为3。另一个难点在于输出,之前写了一个个人觉得没问题然后WA在了第10个(n=100000)样例上。。。后来换了一种方式输出就AC了。
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n;
cin>>n;
int k=sqrt(n);//LIS长度
int t=n-k+1;//输出起点
int m=t;
for(int i=1;i<=n;i++)
{
if(i%k)//分段
{
cout<<m<<' ';
m++;
}
else
{
cout<<m<<' ';
m=t-k;//更新起点
t=t-k;
if(m<=0)m=1;//最后防止可能漏掉1
}
}
cout<<endl;
return 0;
}