题意:给出一串数字,让你求在这一串数字中最长的连续递增子序列,输出结果为长度和这个子序列的下标。
举个例子
6
1 3 5 2 4 6
那么结果就是
2
1 4(或者2 5或者3 6)
思路:和最长上升子序列有点像,不过是弱化版。
递推公式是mp[x]=mp[x-1]+1
mp[x]表示以数字x结尾的最大长度。
mp是容器map
至于存储就是用pre数组来记录。
pre[i]=j,表示第i个数前面那个数的下标是j
然后就是遍历整个map,寻找一个最大值,找到之后只要用vector记录就行了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
map<int, int >pos;//存储每个数的位置
map<int, int >mp;//表示以i为结尾的最大长度
int n;
vector<int>v;
int pre[maxn];
int main() {
scanf("%d", &n);
memset(pre, -1, sizeof(pre));
for(int i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
pos[x] = i;//数字x的位置是i
if(mp[x-1]) {//如果存在数字x-1
mp[x] = mp[x - 1] + 1;
pre[pos[x]] = pos[x - 1];//第i个数的前面的数下标
} else mp[x] = 1;
}
map<int, int>::iterator it;
int MAX = 0;
int p = 0;
for(it = mp.begin(); it != mp.end(); it++) {
if(it->second > MAX) {
MAX = it->second;
p = pos[it->first];
}
}
printf("%d\n", MAX);
while(p != -1) {
v.push_back(p);
p = pre[p];
}
reverse(v.begin(), v.end());
for(int i = 0; i < v.size(); i++) {
if(i != v.size() - 1) printf("%d ", v[i]);
else printf("%d\n", v[i]);
}
return 0;
}