题目大意
给你n个数的序列,求出最长的连续上升子序列(每个元素之间只差1),并输出在原序列中的位置。
input
Copy
7
3 3 4 7 5 6 8
output
Copy
4
2 3 5 6
input
Copy
6
1 3 5 2 4 6
output
Copy
2
1 4
input
Copy
4
10 9 8 7
output
Copy
1
1
input
Copy
9
6 7 8 3 4 5 9 10 11
output
Copy
6
1 2 3 7 8 9
思路: 由于子序列的连续递增的性质(x,x+1,x+2……),我们如果考虑令q[i]表示以数字i作为子序列的最后一个元素(即,以数字 i 结尾)的子序列的长度,那么最后一个元素的前一个元素一定是i-1,长度就在前一个的基础上加一。 表示为q[i]=q[i-1]+1。由于给定的n个数字都可以作为子序列的结尾,我们枚举这n个数字,如果有比a[i]小1的数字在a[i]之前出现过,那么q[a[i]-1]一定被更新过,加1后长度增加。如果没有出现过,加1更新为1.
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<utility> #include<cstring> #include<string> #include<vector> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; typedef pair<int,int> pll; const int maxn=2e5+10; int gcd(int a,int b) { if(!b) return a; else return gcd(b,a%b); } int s[maxn]; int a[maxn]; map<int,int>q; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; for(int i=1;i<=n;i++) { cin >> a[i]; } int maxnum=0; int res; for(int i=1;i<=n;i++) { q[a[i]]=q[a[i]-1]+1; if(q[a[i]]>maxnum) { maxnum=q[a[i]]; res=a[i]; } } cout << maxnum << endl; int cnt=0; for(int i=n;i>=1;i--) { if(a[i]==res) { s[++cnt]=i; res--; } } for(int i=cnt;i>=1;i--) cout << s[i] << " "; return 0; }