题意:
给出m中颜色作为喜欢的颜色(同时也给出顺序),然后给出一串长度为L的颜色序列,现在要去掉这个序列中的不喜欢的颜色,然后求剩下序列的一个子序列,使得这个子序列表示的颜色顺序符合自己喜欢的颜色的顺序,不一定要所有喜欢的颜色都出现
思路:
就是个简单的dp,一遍过,不过我dp不怎么样所以记录一下:
- 用dp[i][j]表示序列中第i个数并且喜欢的颜色在顺序中排j的最大值。
- 当num[i]是喜欢的颜色时,dp[i][j]=max{dp[i][k],k<=j}+1
- 其他情况dp[i][j]=dp[i-1][j]
#include<iostream> #include<string> #include<vector> #include<map> #include<set> #include<stack> #include<sstream> #include<functional> #include<algorithm> using namespace std; const int INF = 0xfffff; const int maxn = 100050; int dp[10005][205]; int num[10005]; map<int, int> order; int main() { int n, m, l,t; scanf("%d", &n); scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d", &t); order[t] = i; } scanf("%d", &l); for (int i = 1; i <= l; i++) scanf("%d", &num[i]); for (int i = 1; i <= l; i++) { if (order.find(num[i]) != order.end()) { int pos = order[num[i]]; int max = -1,index=0; for (int j = 1; j <= pos; j++) { if (max < dp[i - 1][j]) { max = dp[i - 1][j]; index = j; } } dp[i][pos] = dp[i - 1][index] + 1; for (int j = 1; j <= m&&j!=pos; j++) { dp[i][j] = dp[i - 1][j]; } } else { for (int j = 1; j <= m; j++) { dp[i][j] = dp[i - 1][j]; } } } int res = -1; for (int i = 1; i <= m; i++) { if (res < dp[l][i]) { res = dp[l][i]; } } printf("%d", res); return 0; }