codeforces620 D 构造

题意:给定一个数n 和 n-1个字符 代表着这个序列中相邻元素的大小关系是怎样的 然后让我们找到 最大上升子序列长度最小的序列 和 最大上升子序列最大的两组数列 并把它们数组 数列的元素是有1~n组成的

思路:这里我们可以不通过在相应关系符左右位置上放数进行操作而是通过构造出两个新序列 再根据关系符进行相关的变动

这里的构造就是从极端化的反面去考虑 想让LIS最短那么考虑最极端的情况 把1~n直接从大到小排下来 就是最短 然后再去看关系符 最短的时候我们要看的关系符是“<” 因为本身这个序列就符合大于关系,只需要记录下来有几个连续的小于(一定是连续)然后这个连续区间内的元素倒置就可以了 同理最大的时候就找‘>’然后一样的连续区间倒置 即可获得答案

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 2e5+107;

int a[N],b[N];
char s[N];
int n;

bool cmp(int a,int b)
{
    
    
    return a > b;
}

int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        int n;
        cin>>n;
        scanf("%s",s+1);
        for(int i = 1;i <= n;i ++)
            a[i] = n-i+1;
        for(int i = 1;i <= n;i ++)
            b[i] = i;
        for(int i = 1;i < n;)
        {
    
    
            int j = i;
            while(s[j] == '<')
            {
    
    
                j ++;
            }
            sort(a+i,a+j+1);
            i = j + 1;
        }
        for(int i = 1;i < n;)
        {
    
    
            int j = i;
            while(s[j] == '>')
            {
    
    
                j ++;
            }
            sort(b+i,b+j+1,cmp);
            i = j + 1;
        }
        for(int i = 1;i <= n;i ++)
        {
    
    
            if(i != n)
                printf("%d ",a[i]);
            else
                printf("%d\n",a[i]);
        }
        for(int i = 1;i <= n;i ++)
        {
    
    
            if(i != n)
                printf("%d ",b[i]);
            else
                printf("%d\n",b[i]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45672411/article/details/104439151