题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1045
一道简单的DP,跟最大不下降子序列一个思想, 倒着考虑。F[i]表示从下标为i开始的最长题目要求的序列长度。所以状态转移方程为
1 i == length && a[i]属于题目给定序列
F[i]= 0 a[i]不属于题目给定序列
1 i<j<=length && 给定序列中a[i]不在a[j]之前
max{F[j]}+1 i<j<=length && 给定序列中a[i]在a[j]之前
这是个时间复杂度为n平方的做法,不过本题能过。此题中的favorite color 序列每个元素都是unique的。所以用一个数组记录颜色的先后顺序。
1 #include<cstdio> 2 #include<vector> 3 using namespace std; 4 5 6 int main(){ 7 int N,M, L; 8 scanf("%d", &N); 9 vector<int> order(N+1, 0); 10 scanf("%d", &M); 11 for(int i=1; i<M+1; ++i){ 12 int a; scanf("%d",&a); 13 /*order[i]=j 表示颜色i在序列中排名为j*/ 14 order[a] = i; 15 } 16 scanf("%d", &L); 17 vector<int> seq(L); 18 for(int i=0; i<L; ++i) 19 scanf("%d", &seq[i]); 20 vector<int> F(L, 0); 21 for(int i=L-1; i>=0; --i){ 22 if(i == L-1 && order[seq[i]] != 0) 23 F[i]=1; 24 else if(order[seq[i]] == 0) 25 F[i]=0; 26 else{ 27 int max(-1); 28 for(int j=i+1; j<L; ++j){ 29 if(order[seq[i]] <= order[seq[j]]){ 30 if(F[j]+1 > max) 31 max=F[j]+1; 32 } 33 else{ 34 if(max < 1) 35 max = 1; 36 } 37 } 38 F[i]=max; 39 } 40 } 41 int max(-1); 42 for(int i=0; i<L; ++i){ 43 if(F[i] > max) 44 max=F[i]; 45 } 46 printf("%d ", max); 47 return 0; 48 }