UVA - 10534Wavio Sequence(LIS)

来源:互联网 发布:ubuntu怎么配置ip 编辑:程序博客网 时间:2024/06/11 05:08

题目:UVA - 10534Wavio Sequence(LIS)


题目大意:给出N个数字,找出这样的序列:2 * n + 1个数字组成。前面的n + 1个数字单调递增,后面n + 1单调递减。


解题思路:从前往后找一遍LIS,再从后往前找一遍LIS。最后只要i这个位置的LIS的长度和LDS的长度取最小值。再*2 - 1就是这个波浪数字的长度。注意这里的求LIS要用nlog(n)的算法,而且这里的波浪数字的对称并不是要求i的LIS == LDS,而是只要求LIS和LDS最短的长度就行了,长的那个可以取少点。

LIS(nlog(n))算法


代码:

#include <cstdio>#include <cstring>const int maxn = 10005;int dp1[maxn];int dp2[maxn];int v[maxn];int LIS[maxn];int p;int Max (const int a, const int b) { return a > b? a: b; }int bsearch (int s) {int l = 0;int r = p;int mid;while (l < r) {mid = l + (r - l) / 2;if (s > LIS[mid])l = mid + 1;else if (s < LIS[mid])r = mid;elsereturn mid;}return l;}int main () {int n;int k;while (scanf ("%d", &n) != EOF) {for (int i = 0; i < n; i++)scanf ("%d", &v[i]);p = 0;LIS[p] = v[0];dp1[0] = 1;//注意dp2[n - 1] = 1;for (int i = 1; i < n; i++) {if (v[i] > LIS[p]) {LIS[++p] = v[i]; dp1[i] = p + 1;} else if (v[i] < LIS[p]) {k = bsearch (v[i]);dp1[i] = k + 1;LIS[k] = v[i];} elsedp1[i] = p + 1;}p = 0;LIS[p] = v[n - 1];for (int i = n - 2; i >= 0; i--) {if (v[i] > LIS[p]) {LIS[++p] = v[i];dp2[i] = p + 1;} else if (v[i] < LIS[p]) {k = bsearch (v[i]);dp2[i] = k + 1;LIS[k] = v[i];} else dp2[i] = p + 1;}int ans = 1;for (int i = 0; i < n; i++) {if (dp1[i] <= dp2[i])ans = Max (ans, 2 * dp1[i]);elseans = Max (ans, 2 * dp2[i]);}/*for (int i = 0; i <= p; i++)printf ("%d ", LIDS[i]);printf ("\n");*/printf ("%d\n", ans - 1);}return 0;}



0 0
原创粉丝点击