题意:
给定N≤105的一个序列,现在有一个deque
将序列按顺序往deque里添加,只能向deque的头或者尾添加,或者丢弃这个数
唯一的要求是deque里的数必须是不降的,求deque里的最多元素个数是多少
分析:
其实就是以Ax开头的max(最长下降子序列与最长不降子序列的和,最长不升子序列与最长上升子序列的和)
题解的方法代码很简单
如果用BIT要搞2遍,数据水了一遍也过了,参考下列数据2
6
4 5 4 6 7 8
6
4 3 4 6 7 8
ans:
6
6
代码:
//
// Created by TaoSama on 2016-02-26
// Copyright (c) 2016 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, a[N];
int f[2][N], h[N];
//start from i, 0 for longest non-increasing, 1 for non-decreasing
int same[2][N]; //start from i, in LIS sequence, same as a[i]
void gao(int *f, int *same) {
memset(h, 0x3f, sizeof h);
for(int i = n; i; --i) {
f[i] = upper_bound(h + 1, h + 1 + n, a[i]) - h;
h[f[i]] = a[i];
auto range = equal_range(h + 1, h + 1 + n, a[i]);
same[i] = range.second - range.first;
}
}
int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
int t; scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", a + i);
gao(f[0], same[0]);
for(int i = 1; i <= n; ++i) a[i] = -a[i];
gao(f[1], same[1]);
int ans = 0;
for(int i = 1; i <= n; ++i)
ans = max(ans, f[0][i] + f[1][i] - min(same[0][i], same[1][i]));
printf("%d\n", ans);
}
return 0;
}
给个搞一遍的代码吧,懒得再写再搞一遍了
代码:
//
// Created by TaoSama on 2016-02-26
// Copyright (c) 2016 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, a[N];
struct BIT {
int n, b[N];
void init(int _n) {
n = _n;
memset(b, 0, sizeof b);
}
void add(int i, int v, int delta) {
for(; i && i <= n; i += delta * (i & -i))
b[i] = max(b[i], v);
}
int sum(int i, int delta) {
int ret = 0;
for(; i && i <= n; i -= delta * (i & -i))
ret = max(ret, b[i]);
return ret;
}
} bit;
int f[N];
int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
int t; scanf("%d", &t);
while(t--) {
scanf("%d", &n);
vector<int> xs;
for(int i = 1; i <= n; ++i) {
scanf("%d", a + i);
xs.push_back(a[i]);
}
sort(xs.begin(), xs.end());
xs.resize(unique(xs.begin(), xs.end()) - xs.begin());
//start from i, longest non-increasing, to left
bit.init(xs.size());
for(int i = n; i; --i) {
a[i] = lower_bound(xs.begin(), xs.end(), a[i]) - xs.begin() + 1;
f[i] = bit.sum(a[i], 1) + 1;
bit.add(a[i], f[i], 1);
}
//start from i, longest non-decreasing, to right
bit.init(xs.size());
int ans = 0;
for(int i = n; i; --i) {
int cur = bit.sum(a[i], -1) + 1;
bit.add(a[i], cur, -1);
//ignore same numbers this time
int rhs = bit.sum(a[i] + 1, -1);
ans = max(ans, f[i] + rhs);
}
printf("%d\n", ans);
}
return 0;
}