最长上升子序列

博客围绕一个C++编程问题展开,已知1到n排列中以第i个位置结尾的最长上升子序列长度数组,需构造符合条件的排列p,若不存在则输出 -1。给出了输入输出要求,介绍解题思路为判断数组连续性,标记元素出现次数并做前缀和处理,还提及了AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

你原本有一个 1 到 n 的排列,但是不慎地,你遗忘了它,但是你记得以 第i个位置 结尾的最长上升子序列的长度数组 {an} ,现在希望你能够构造一个符合条件的排列 p ,如果不存在符合上述条件的排列 p ,则输出  - 1。

这里定义以 第i位置 结尾的最长上升子序列的长度,为符合以下条件的整数数组 

1 ≤id1 < id2 < id3 < ··· < idk = i

pid1 < pid2 < pid3 < ··· < pid

 中 k 的最大值。

本题输入输出量比较大,请选手注意。

Input

第一行一个整数 n (1 ≤ n ≤ 106)

第二行 n 个整数表示数组 {an} (1 ≤ ai ≤ n),其中 ai 表示以 i 结尾的最长上升子序列的长度。

Output

一行 n 个整数表示排列 p ,如果无解,则输出  - 1。

解题思路:

连续的a=1到an=a(n-1)-1,不连续就输出“-1”;

否则标记数组的元素出现次数,并进行前缀和处理,保证1~n的出现。
 

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main()
{
    int n,ff=0;
    cin>>n;
    b[0]=1;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[a[i]]++;
        if(b[a[i]-1]==0)
        {
            ff=1;
            break;
        }   
    }
    if(ff==1)   cout<<"-1"<<'\n';
    else
    {
        for(int i=2;i<=n;i++)   b[i]=b[i]+b[i-1];
        for(int i=1;i<=n;i++)
        {
            cout<<b[a[i]]<<" ";
            b[a[i]]--;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值