题目来源:最长上升子序列 - Gym 104725F - Virtual Judge (vjudge.net)
题目描述:给定n个最长上升子序列长度,求出这个序列的任意一种可能,若找不到则输出-1。
解题思路:先判断这个子序列是否成立,在成立的基础上对这些子序列的个数进行前缀和处理,然后遍历数组,按子序列长度最大的可能数从大到小输出这些数。(具体看代码)
实现代码:
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N=1e6+5;
int a[N],b[N];
void solve(){
int n;
cin >> n;
int flag=0;//判断子序列的长度是否成立
b[0]=1;
int mx=0;
for(int i=1;i<=n;++i){
cin >> a[i];
mx=max(mx,a[i]);
b[a[i]]++;//统计子序列长度的个数
if(b[a[i]-1]==0){//若相邻的子序列长度超过1,则当前序列不成立
flag=1;
break;
}
}
if(flag){
cout << "-1";
return ;
}
for(int i=2;i<=mx;++i){
b[i]+=b[i-1];//前缀和处理长度个数
}
for(int i=1;i<=n;++i){
cout << b[a[i]] << " ";//从大到小输出当前子序列的最大数
b[a[i]]--;//输出完后删去这个数
}
return ;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
//cin >> t;
//while(t--)
solve();
return 0;
}