题目描述
查看题目信息
给定一个长度为n的整数数组。 你必须选择这个最大长度数组的某个子序列这样这个子序列就形成了一个递增的连续整数序列。换句话说,对于某个值x和长度k,所需的序列应该等于[x,x+1,..., x+k - 1]。 数组的子序列可以通过擦除数组中的一些(可能为零)元素来获得。你可以擦掉任何元素,不一定是连续的。其余元素保持它们的顺序。例如,对于数组[5,3,1,2,4],以下数组是子序列:[3],[5,3,1,2,4],[5,1,4],但是数组[1,3]不是。
输入格式
第一行是1个整数n(1≤n≤2⋅105)
第二行是n个整数(数值范围在1~10^9之间),代表一个序列,中间以空格隔开
输出格式
第一行打印最长子序列的长度k
第二行打印子序列中的每个数在原序列中对应的序号
注意!如果符合要求的长度为k的子序列不止1个,输出其对应序号中字典序最小的。
样例输入
7 3 3 4 7 5 6 8
样例输出
4 1 3 5 6
样例输入
6 1 3 5 2 4 6
样例输出
2 1 4
样例输入
4 10 9 8 7
样例输出
1 1
问题提示
一道map练手题,可以结合动态规划实现
#include <iostream>
#include <map>
using namespace std;
#define int long long
#define F(i,a,b) for(int i=(a);i<=(b);i++)
#define R(i,a,b) for(int i=(a);i>=(b);i--)
//dp[x]=l 以x作为结尾的递增子序列最长长度为l
const int N=2e5+5;
map<int,int> m;
int n,cur,maxL,last,num;
int a[N];
map<int,int> dp;
signed main()
{
//输入数据
cin>>n;
F(i,1,n)
{
//输入数据
cin>>a[i];
dp[a[i]]=dp[a[i]-1]+1;//更新以a[i]结尾的递增子序列的最长长度
if(dp[a[i]]>maxL)
{
maxL=dp[a[i]];//更新最长长度
last=a[i];//更新递增序列的最后一个元素
}
}
//输出最长子序列的长度
cout<<maxL<<"\n";
//Q2
num=last-maxL+1;//求序列的开始元素
F(i,1,n)
{
//如果a[i]是序列的第num个元素
if(a[i]==num)
{
//打印子序列中的每个数在原序列中对应的序号
cout<<i<<" ";
//找第二个元素
num++;
}
}
return 0;
}