现在的位置: 首页 > 综合 > 正文

【PAT Advanced Level】1045. Favorite Color Stripe (30)

2018年03月22日 ⁄ 综合 ⁄ 共 1160字 ⁄ 字号 评论关闭

这几天在复习动态规划(DP),故在pat上找了两道dp的题目来练练手。

这一题看似跟动态规划扯不上,其实是可以把它看做动态规划问题——最长递增子序列(LIS)问题的一个变形。

题目中给定的第一个数组a[n],就相当于给定了“递增”的顺序。如果一个元素a[i]在a中的下标大于或等于另一个元素a[j](i>=j),我们就称a[i]>a[j]

故只需把原来LIS问题中的判断大小部分改为现在的判定大小的规则,基本就可以了。

还有几个注意点:出现在b[m]里,但a[n]里没有的元素,他们是没有顺序的,我们可以直接忽略这样的元素。

代码如下(建议先去看一看LIS问题再来看这一道题):

#include <iostream>
#include <fstream>
using namespace std;

int N, M, P;
int *a;
int *b;
int *L;

int *stp;
const int MINNUM = -999;

bool compare(int tmp1, int tmp2)
{
	if(stp[tmp2 - 1] == -1)
		return false;
	if(stp[tmp1 - 1] >= stp[tmp2 - 1])
		return true;
	else
		return false;
}
bool isExist(int tmp)
{
	if(stp[tmp - 1] != -1)
		return true;
	return false;
}

void LIS()
{
	for(int j = 0; j < P; j++)
	{
		int max = MINNUM;
		if(!isExist(b[j]))
			continue;
		for(int p = 0; p < j; p++)
		{
			if(compare(b[j], b[p]))
				max = max > L[p] ? max : L[p];
		}
		if(max == MINNUM)
			continue;
		else
			L[j] = max + 1;
	}
}


int main()
{
	//fstream cin("a.txt");
	cin>>N>>M;

	stp = new int[N];
	for(int i = 0; i < N; i++)
		stp[i] = -1;

	a = new int[M];
	int tmp = 0;
	while (tmp < M)
	{
		cin>>a[tmp];
		stp[a[tmp] - 1] = tmp;
		tmp++;
	}
	cin>>P;
	b = new int[P];
	tmp = 0;
	while (tmp < P)
	{
		cin>>b[tmp];
		tmp++;
	}
	L = new int[P];
	for(int i = 0; i < P; i++)
		if(isExist(b[i]))
			L[i] = 1;
		else
			L[i] = -1;

	LIS();
	int maxnum = -2;
	for(int i = 0; i < P; i++)
		if(L[i] > maxnum)
			maxnum = L[i];
	if(maxnum > 0)
		cout<<maxnum<<endl;
	else
		cout<<0<<endl;
	//system("Pause");
}

抱歉!评论已关闭.