题解 CF1304D 【Shortest and Longest LIS】
这道题构造方法感觉很多,我就说一说自己的吧。据我所知我的写法应该算是很简洁的。
题目大意
有一个
数据范围
解题过程
首先考虑构造最短的 LIS。
容易发现此时答案的下界是连续相邻 '<' 的长度的最大值。现在我们尝试打到这个最大值。
我们可以这么构造:首先让这个排列等于 '<',我们直接把对应的位置翻转。
这样对于任意两个位置 '<' 对应的区间之内,否则一定满足
然后我们考虑构造最长的 LIS。
有了上面的思考过程,这次我们只需要让这个排列初始等于 '>' 对应的区间。这样对于任意两个位置 '>' 对应的区间之内,否则一定满足
时间复杂度
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int t,n,p[200005];
char s[200005];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%s",&n,s+1);
for(int i=1;i<=n;i++)p[i]=n-i+1;
for(int i=1;i<n;)
{
int j=i;
while(s[j]=='<')j++;
reverse(p+i,p+j+1);
i=j+1;
}
for(int i=1;i<=n;i++)printf("%d ",p[i]);
printf("\n");
for(int i=1;i<=n;i++)p[i]=i;
for(int i=1;i<n;)
{
int j=i;
while(s[j]=='>')j++;
reverse(p+i,p+j+1);
i=j+1;
}
for(int i=1;i<=n;i++)printf("%d ",p[i]);
printf("\n");
}
return 0;
}