题意:给你一个正确的序列,求下面的序列的最长公共子序列。要注意的一点是,这题所给的序列需要经过转换。
http://www.byywee.com/page/M0/S259/259491.html 具体参考这里。
思路:将输入序列转换后,类似于求上升字序列,只不过将大于这个谓词换成一个判断函数,判断一个值是否在另一个值之前出现过。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
int base[50];
int a[50];
int dp[50];
int n;
int indexof(int x){
for(int i = 0; i < n; i++)
if(base[i] == x)
return i;
}
bool check(int x, int value){//在x之前有value存在
int index = indexof(x);
for(int i = 0; i < index; i++)
if(base[i] == value)
return true;
return false;
}
void convert(int x[]){
int temp[50];
for(int i = 0; i < n; i++)
temp[x[i]-1] = i+1;
for(int i = 0; i < n; i++)
x[i] = temp[i];
}
int solve(){
int maximum = 1;
for(int i = 1; i < n; i++){
for(int j = 0; j < i; j++)
if(dp[j]+1 > dp[i] && check(a[i],a[j])){
dp[i] = dp[j]+1;
maximum = max(maximum,dp[i]);
}
}
return maximum;
}
int main(){
scanf("%d",&n);
for(int i = 0; i < n; i++)
scanf("%d",&base[i]);
convert(base);
while(scanf("%d",&a[0]) == 1){
for(int i = 1; i < n; i++)
scanf("%d",&a[i]);
convert(a);
for(int i = 0; i < n; i++)
dp[i] = 1;
printf("%d\n",solve());
}
return 0;
}