点击链接PAT甲级-AC全解汇总
题目:
Eva is trying to make her own color stripe out of a given one. She would like to keep only her favorite colors in her favorite order by cutting off those unwanted pieces and sewing the remaining parts together to form her favorite color stripe.
It is said that a normal human eye can distinguish about less than 200 different colors, so Eva’s favorite colors are limited. However the original stripe could be very long, and Eva would like to have the remaining favorite stripe with the maximum length. So she needs your help to find her the best result.
Note that the solution might not be unique, but you only have to tell her the maximum length. For example, given a stripe of colors {2 2 4 1 5 5 6 3 1 1 5 6}. If Eva’s favorite colors are given in her favorite order as {2 3 1 5 6}, then she has 4 possible best solutions {2 2 1 1 1 5 6}, {2 2 1 5 5 5 6}, {2 2 1 5 5 6 6}, and {2 2 3 1 1 5 6}.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤200) which is the total number of colors involved (and hence the colors are numbered from 1 to N). Then the next line starts with a positive integer M (≤200) followed by M Eva’s favorite color numbers given in her favorite order. Finally the third line starts with a positive integer L (≤104 ) which is the length of the given stripe, followed by L colors on the stripe. All the numbers in a line a separated by a space.
Output Specification:
For each test case, simply print in a line the maximum length of Eva’s favorite stripe.
Sample Input:
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
Sample Output:
7
题意:
按照给定顺序,从一串数种找出与该顺序相符合的子序列最大长度。
没有学过算法,这种题刚上来有点蒙,看了各路大神的dp思路,还是觉得柳神写得最清楚。借鉴了一下思路。学海无涯。
思路:
先把数串过滤不在排名中的数字,剩下的最次长度也是1;
从前往后对于对于每个数而言,到此为止的最大长度(是以该节点为终点,不然没法考虑到排名为51111的情况),分两种情况
- 如果前面没有比自己排名低的,那么以此为end最大长度就是1;
- 如果前面有比自己排名低的,那么以此为end最大长度就是之前最大比自己排名低的那个数作为end的长度+1
我的代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int N,M,L;
cin>>N>>M;
int rank[N+1]={0};
for(int i=1;i<=M;i++)
{
int num;
cin>>num;
rank[num]=i;//rank[2]=1 数字2的排名是1
}
cin>>L;
vector<int>nums;
for(int i=0;i<L;i++)
{
int num;
cin>>num;
if(rank[num])nums.push_back(num);//没有排名的数就不考虑了
}
int max_i[nums.size()]={0},max_res=0;
for(int i=0;i<nums.size();i++)
{
max_i[i]=1;
for(int j=0;j<i;j++)//向前找最大的
if(rank[nums[j]]<=rank[nums[i]])
max_i[i]=max(max_i[i],max_i[j]+1);
max_res=max(max_i[i],max_res);
}
cout<<max_res<<endl;
return 0;
}