PAT A1045 Favorite Color Stripe
思路:先将喜欢的长度为 M 的颜色序列映射到 0 ~ M-1,之后直接将不喜欢的颜色序列删去,重新整理得到映射后存留的颜色序列a,此时存留的序列一定都是喜欢的颜色。
再按照LIS的模板,dp[i]代表a[i]结尾的最长序列,状态转移方程为dp[i] = max{dp[j]} + 1, 0 < j < i,且满足a[j] <= a[i]即不递减。
//LIS
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXC = 210;
const int MAXN = 10010;
int hashTable[MAXC], a[MAXN], dp[MAXN];
int main() {
int numColor, M;
scanf("%d%d", &numColor, &M);
fill(hashTable, hashTable + MAXC, -1);
int color;
for(int i = 0; i < M; i++) {
scanf("%d", &color);
hashTable[color] = i;
}
int totalColor, num = 0;
scanf("%d", &totalColor);
for(int i = 0; i < totalColor; i++) {
scanf("%d", &color);
if(hashTable[color] >= 0)
a[num++] = hashTable[color];
}
int ans = -1;
for(int i = 0; i < num; i++) {
dp[i] = 1;
for(int j = 0; j < i; j++)
if(a[j] <= a[i] && dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
ans = max(ans, dp[i]);
}
printf("%d", ans);
return 0;
}
//LCS
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXC = 210;
const int MAXN = 10005;
int A[MAXC], B[MAXN], dp[MAXC][MAXN];
int main() {
int N, M;
scanf("%d%d", &N, &M);
for(int i = 1; i <= M; i++)
scanf("%d", &A[i]);
int L;
scanf("%d", &L);
for(int i = 1; i <= L; i++)
scanf("%d", &B[i]);
for(int i = 1; i <= M; i++) {
for(int j = 1; j <= L; j++) {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
if(A[i] == B[j]) dp[i][j] += 1;
}
}
printf("%d", dp[M][L]);
return 0;
}