1. 程式人生 > >CodeFroces 977F. Consecutive Subsequence

CodeFroces 977F. Consecutive Subsequence

題意:給出一個長為n的序列,求出最長的遞增序列且該序列公差為1.

解法:首先可以發現n只有2e5,但是數字範圍a是1-1e9.    n相比a很小,所以一貫的套路就是離散化n個數字。

           由於這個遞增序列公差必須為1,我們考慮dp,遞推式就是dp[i]=dp[i-1]+1,i代表當前數字大小,dp[i]代表算上i最長的序列是多長。

            由於數字太大,不可能開1e9的dp陣列,所以就回到了離散化的問題上。最直接的方法就是用map來代替陣列。

            複雜度為O(nlogn)

程式碼如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
const long long INF = 1e18;

int n, ans = 0, a[maxn], Max = 0;
map <int, int> Map;

int main() {
	ios::sync_with_stdio(0);
	cin >> n;
	for(int i = 1, tmp; i <= n; i++) {
		cin >> tmp;
		a[i] = tmp;
		if(Map.find(tmp - 1) == Map.end()) {
			Map[tmp] = 1;
			if(ans < Map[tmp]) {
				ans = Map[tmp];
				Max = tmp;
			}
		} else {
			Map[tmp] = max(Map[tmp - 1] + 1, Map[tmp]);
			if(ans < Map[tmp]) {
				ans = Map[tmp];
				Max = tmp;
			}
		}
	} 
	cout << ans << endl;
	int p = Max - ans + 1;
	for(int i = 1; i <= n; i++) {
		if(a[i] == p) {
			cout << i;
			p++;
			if(p > Max)
				cout << '\n';
			else
				cout << ' ';
		}
	}
	return 0;
}