题目链接:uva 12002 - Happy Birthday
题目大意:给出一个序列,表示说有n个碟子,每个数字代表碟子的大小,现在开始堆碟子,可以选择在上面和下面放,不过放上面的碟子必须小于等于最上面的碟子,放在下面的碟子必须大于等于最下面的碟子。问说最多能放多少碟子。
解题思路:和uva 11456 做法相似,只不过说这题可以取相同的大小,那么只需要分成两种情况考虑即可,一种是将当前起始的值归入升序中,一种是归进降序中。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 505; int n, s[N], up[N], down[N]; void init () { for (int i = 1; i <= n; i++) scanf("%d", &s[i]); for (int i = n; i; i--) { up[i] = down[i] = 1; for (int j = n; j > i; j--) { if (s[j] <= s[i]) down[i] = max(down[i], down[j] + 1); if (s[j] >= s[i]) up[i] = max(up[i], up[j] + 1); } } } int cat (int k, int p, int a) { int ans = 0; for (int i = p; i <= n; i++) { if (a == 1 && s[i] >= k) ans = max(ans, up[i]); if (a == -1 && s[i] <= k) ans = max(ans, down[i]); } return ans; } int solve () { int ans = 0; for (int i = 1; i <= n; i++) { int u = up[i] + cat(s[i]-1, i, -1); int v = down[i] + cat(s[i]+1, i, 1); ans = max(ans, max(u, v)); } return ans; } int main () { while (scanf("%d", &n) == 1 && n) { init (); printf("%d\n", solve()); } return 0; }