题目描述
原题
这题意都让我理解了半天- -
题目大意:给出M种颜色作为喜欢的颜色(同时也给出顺序),然后给出一串长度为L的颜色序列,现在要去掉这个序列中的不喜欢的颜色,然后求剩下序列的一个子序列,使得这个子序列表示的颜色顺序符合自己喜欢的颜色的顺序,不一定要所有喜欢的颜色都出现
参考
https://blog.csdn.net/liuchuo/article/details/52254507
思路
使用最长不下降子序列的方法
stripe[favColor] = i;
记录的是当前favColor颜色在最喜欢的序列中排第几个
dp[i]
表示以第i个布条为结尾能缝出的最长布料长度,初始状态是1
if(stripe[cloth[i]]>=stripe[cloth[j]])
dp[i] = max(dp[i],dp[j]+1);
上面这个if语句是指:如果布条cloth[i]的颜色可以排在在布条cloth[j]的的颜色的后面,那么就可以把布条cloth[i]接在布条cloth[j]的后面,这个接起来的布条的长度就是dp[j]+1
AC代码
#include<iostream>
using namespace std;
int stripe[201];
int cloth[10010];
int ith;
int main(){
int N,M,L;
cin>>N>>M;
int favColor;
for(int i = 1;i<=M;++i){
cin>>favColor;
stripe[favColor] = i; //在序列中排第几个
//有个隐含前提是最爱的颜色序列中没有重复颜色
}
cin>>L;
int color;
for(int i = 0;i<L;++i){
cin>>color;
//如果这个颜色是喜爱的颜色之一 ,才记录到数组中
if(stripe[color]>0)
cloth[ith++] = color;
}
int dp[ith];
int res = 0;
//动态规划 最长不下降子序列
for(int i = 0;i<ith;++i){
dp[i] = 1; //初始只有它自己,布料长度为1
for(int j = 0;j<i;++j){
if(stripe[cloth[i]]>=stripe[cloth[j]])
dp[i] = max(dp[i],dp[j]+1);
}
res = max(res,dp[i]);
}
cout<<res;
return 0;
}