伊娃试图用一条原始色带给自己制作一条喜欢的色带。
她会通过剪掉原始色带中多余的部分,将其余部分拼接起来,从而使得色带中只包含她喜欢的颜色,并且这些颜色按照她喜欢的顺序排列。
据说正常的人眼只能分辨不到 200 种不同的颜色,因此伊娃喜欢的颜色数量是有限的。
原始色带的长度可能会很长,她希望拼剪成的能够使她满意的色带也尽可能的长。
因此,她需要你来帮她确定能够拼剪出的,使得她满意的色带的最大可能长度。
注意,修剪方案可能并不唯一,例如给定颜色为 {2 2 4 1 5 5 6 3 1 1 5 6} 的色带,如果伊娃最喜欢的颜色以她最喜欢的顺序排列为 {2 3 1 5 6},则她有 4 种可能的最佳解决方案 {2 2 1 1 1 5 6},{2 2 1 5 5 5 6},{2 2 1 5 5 6 6},{2 2 3 1 1 5 6}。
拼剪而成的色带不一定要包含所有她喜欢的颜色,但是一定不能包含她不喜欢的颜色,并且包含的颜色之间的相对顺序应该与她喜欢的顺序保持一致。
输入格式
第一行包含整数 N,表示涉及到的颜色总数,颜色编号依次为 1∼N。
第二行首先包含一个整数 M,表示她喜欢的颜色数量,接下来会按照她喜欢的排列顺序,依次给出她喜欢的 M 种颜色的编号。
第三行首先包含一个整数 L,表示原始色带的长度,然后包含 L 个整数,表示原始色带的具体颜色分布。
输出格式
输出一个整数,表示她能够满意的色带的最大长度。
数据范围
1≤N≤200,
1≤M≤200,
1≤L≤104
输入样例:
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
输出样例:
7
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int a[N],b[210];
int dp[N];
int n,m,k;
int main(){
cin>>n;
cin>>m;
for(int i=1;i<=m;i++)cin>>b[i];
cin>>k;
for(int i=1;i<=k;i++)scanf("%d",&a[i]);
for(int i=1;i<=k;i++){
bool flag=false;
for(int j=1;j<=m;j++){
if(a[i]==b[j]){
a[i]=j;//赋予权值
flag=true;
break;
}
}
if(flag==false)a[i]=10000;//不喜欢的颜色赋予最大值,不考虑
}
if(a[1]<=m)dp[1]=1;
int maxv=dp[1];
for(int i=2;i<=k;i++){
if(a[i]<=m){//是合法颜色
dp[i]=1;//合法颜色的长度最短为1,前面都是不合法的
for(int j=1;j<i;j++){
if(a[j]<=a[i]&&(dp[j]+1>dp[i])&&a[j]<=m){
dp[i]=dp[j]+1;
}
}
maxv=max(maxv,dp[i]);
}
}
cout<<maxv<<endl;
return 0;
}
#include <iostream>
using namespace std;
const int N = 210, M = 10010;
int n, m, l;
int p[N], s[M];
int f[N][M];//f[i][j]表示p[1]到p[i]和s[1]到s[j]最大公共部分
int main()
{
cin >> n;
cin >> m;
for (int i = 1; i <= m; i ++ ) cin >> p[i];
cin >> l;
for (int i = 1; i <= l; i ++ ) cin >> s[i];
for (int i = 1; i <= m; i ++ )
for (int j = 1; j <= l; j ++ )
{
f[i][j] = max(f[i - 1][j],f[i][j-1]);
//f[i][j - 1]+1不能写成f[i - 1][j - 1]+1,因为比如3 5和3 5 5
if (p[i] == s[j]) f[i][j] = max(f[i][j], f[i][j - 1] + 1);
}
cout << f[m][l] << endl;
return 0;
}