dp[i][j] 表示a(1,i),b(1,j)取以a[i], b[j]结尾的最大公共上升子串的大小
#include <iostream>
using namespace std;
const int N = 205;
int dp[N][N];
int a[N];
int main() {
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
int ans = 1;
for(int i = 1; i <= n; i++) {
int max = 0;
for(int j = n; j > i; --j) {
dp[i][j] = dp[i-1][j];
if(a[i] == a[j] && dp[i][j] < max + 1)
dp[i][j] = max + 1;
if(a[i] > a[j] && dp[i-1][j] > max) //在b串中, 取一个小于a[i]的数结尾的最大长度
max = dp[i-1][j];
if(dp[i][j]*2 > ans)
ans = dp[i][j] * 2;
for(int k = i; k < j; k++) { //判断中间是否存在一个很大的数
if(a[k] > a[j]) {
if(2*dp[i][j]+1 > ans)
ans = 2 * dp[i][j] + 1;
}
}
}
}
printf("%d\n", ans);
}
return 0;
}
刚开始的做法是:取一个点,将a数组分成两个部分。前面的为b,后面的为c。将前面的逆置。然后判断最长公共上升序列。问题在于判断中间是否存在很大的数比较困难。要记录开始的点。。搞了半天WA。
而采取不逆置的方法。将从两端开始像中间比较。这样显然容易知道中间的数字与最后一个相等数字的关系。。如以上代码所示。。