您的位置:首页 > 产品设计 > UI/UE

HDU 4604 Deque(dp、LIS)

2016-02-28 00:32 447 查看
题意:

给定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
;
int f[2]
, h
;
//start from i, 0 for longest non-increasing, 1 for non-decreasing
int same[2]
; //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
;

struct BIT {
int n, b
;
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
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp LIS