PAT 1045 Favorite Color Stripe (30) 分动态规划 最长前缀问题 燚

版权声明:哈哈 你能采纳 我很开心 https://blog.csdn.net/m0_38090681/article/details/84349707

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 (≤10​4​​) 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

题目大意:用正整数表示颜色,第一行给定颜色范围上限N,第二行:给定Each喜欢的颜色个数M 紧接着给出M个他喜欢的颜色数字。第三行:给出总的颜色个数L 紧接着给出L个颜色。要求:从L个颜色中筛选出Each喜欢的最长颜色串,且颜色的相对次序和他喜欢的颜色的相对顺序一致,不要求包含他所有喜欢的颜色。

   思路:1.读完题的第一感觉为  动态规划,因为每一个颜色的选定都依赖于前面求出的最大字串,具有最优子结构性,不同的选择方案间又有重叠  即 子问题重叠性,这是动态规划的基本性质

              2.明确算法后 就开始设计。要求最长前缀序列,于是每一次的更新就必须在前一次的基础上进行,动态规划是用空间换时间的方法,由于该题只求最长前缀的长度,不要求回溯。所以就只开辟一个n+1的数组count。(如果此题要求找出所有最长前缀的情况,则需要开辟L*M的二维数组,以便最后回溯寻找所有情况)。

              3.具体算法:1.将Each喜欢的颜色存在loveColor的数组中,总的颜色存在allColor的数组中。

                                   2.依次取出loverColor中的元素loverColor[i]与allColor中的元allColor[j]素逐个比较,如果                                                                      allColor[j]==loverColor[i],则在计数数组count上执行操作count[j+1]+=1(表示allColor[j+1]的最长前缀数                                         目),如果allColor[j]!=loverColor[i],则比较count[j]与count[j+1]的大小,如果count[j+1]<count[j]则表                                         示有比现在更长的前缀,因此更新count[j+1]=count[j].

                                  3.重复2操作直至loveColor末尾,最后count[n]上的数即为最长前缀数量。

难点:理解动态规划过程。

#include<iostream>
#include<vector>
using namespace std;
int G[10001];
void input(vector<int>&loveColor,vector<int>&allColor){
	int n;
	cin>>n;
	int m;
	cin>>m;
    //输入并判断loveColor是否在范围内
	for(int i=0;i<m;i++){
		int temp;
		cin>>temp;
		if(temp>=1&&temp<=n)
			loveColor.push_back(temp);
	}
	cin>>m;
    //输入并判断allColor是否在范围内
	for(int i=0;i<m;i++){
		int temp;
		cin>>temp;
		if(temp>=1&&temp<=n)
			allColor.push_back(temp);
	}
}
//计数并求出最长前缀
void computeTheMax(vector<int>&loveColor,vector<int>&allColor){
	for(int i=0;i<loveColor.size();i++){
		int j=0;
        //从左到右逐个检测allColor[j]是否等于loveColor[i]
		while(allColor[j]!=loveColor[i]&&j<allColor.size())
			j++;
		G[j+1]+=1;//在j的下一位加以,表示G[j+1]前的最长前缀数
		j++;
        //判断并更新后面的前缀数目
		for(;j<allColor.size();j++){
			if(allColor[j]==loveColor[i])
			G[j+1]=G[j]+1;
		else if(G[j]>G[j+1])
			G[j+1]=G[j];
		}
	}
}
int main(){
	vector<int>loveColor;
	vector<int>allColor;
	input(loveColor,allColor);
	computeTheMax(loveColor,allColor);
	cout<<G[allColor.size()]<<endl;
}

猜你喜欢

转载自blog.csdn.net/m0_38090681/article/details/84349707
今日推荐