解題思路:這道題與最長上升字序列有些類似,只不過是個對稱的最長上升子序列。解題思路仍是動態規劃。
子問題:前j個數字和後i個數字組成的序列中的隊形長度。
狀態轉移: 如果a[i] == a[j] 那麼隊列的長度等於前j-1和後i-1個數字組成的隊列中中間數字小於a[i]的隊列的長度加上2,
代碼如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 250;
int f[MAXN], a[MAXN];
int main()
{
int t, i, n, j, curlen, ans;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
ans = 1;
memset(f, 0, sizeof(f)); //注意memset的正確形式: 如果寫memset(f, 0, MAXN)會出現答案錯誤
for(i = n; i > 0; i--)
{
curlen = 0;
for(j = 1; j <= i; j++)
{
if(a[j] < a[i]) //查找並記錄比a[i]小的數形成的最長長度,
{
curlen = max(curlen, f[j]); //
}
else if(a[j] == a[i]) //如果相等,最長長度可以再加一
{
f[j] = curlen+1;
if(j < i) ans = max(ans, 2 * f[j]);
else ans = max(ans, 2 * f[j] - 1); //考慮長度爲奇數的情況,要減1
}
}
}
printf("%d\n", ans);
}
return 0;
}