POJ 1836 Alignment(DP | LIS)

来源:互联网 发布:eia美国原油最新数据 编辑:程序博客网 时间:2024/05/06 00:07

题意:有一个序列,现在从中去除一些数,使得每个数比左边或右边的所有数都大。

思路:LIS。可以看出最后答案中的序列一定是一个递增或递减或一个递增加一个递减序列组成,所以我们可以预处理出每个位置左边最长上升子序列的长度,和右边最长下降子序列的长度,然后扫一遍求出相邻位置的二者和的最大值就是最后序列中的元素数量。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 1005;const double INF = 10;int n;int le[MAXN], ri[MAXN];double a[MAXN], g[MAXN];int main() {    //freopen("input.txt", "r", stdin);while(scanf("%d", &n) == 1) {for(int i = 1; i <= n; i++) scanf("%lf", &a[i]);memset(le, 0, sizeof(le));memset(ri, 0, sizeof(ri));for(int i = 1; i <= n; i++) g[i] = INF;for(int i = 1; i <= n; i++) {int k = lower_bound(g+1, g+n+1, a[i]) - g;le[i] = max(k, le[i-1]);g[k] = a[i];}for(int i = 1; i <= n; i++) g[i] = INF;for(int i = n; i; i--) {int k = lower_bound(g+1, g+n+1, a[i]) - g;ri[i] = max(k, ri[i+1]);g[k] = a[i];}int ans = 0;for(int i = 0; i <= n; i++) ans = max(ans, le[i]+ri[i+1]);cout << n - ans << endl;}    return 0;}

0 0