标签:blog http io for ar 2014 art cti
题目: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最短的长度就行了,长的那个可以取少点。
代码:
#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; else return 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]; } else dp1[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]); else ans = 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; }
UVA - 10534Wavio Sequence(LIS),布布扣,bubuko.com
UVA - 10534Wavio Sequence(LIS)
标签:blog http io for ar 2014 art cti
原文地址:http://blog.csdn.net/u012997373/article/details/38543075