动态规划 NOI 1996:登山——正序、逆序各求一次最大上升子序列长

点击打开链接

题目大意:从左到右游览,从低往高走,再从高往低走(不能走两个海拔一样的),求最多能经过的点的数目

注意两点:

1、不能从头开始找逆序列

2、注意指针类型会识别为long int,必须强制转换

AC1:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[1001],lmax[1001],rmax[1001];
int main()
{
	int n,i,ans,*j,s[1001],t;
		cin>>n;
		for (i=1;i<=n;i++)
			cin>>a[i];
		int top=0;
		lmax[1]=1;
		memset(s,0,sizeof(s));
		s[++top]=a[1];
		for (i=2;i<=n;i++)
		{
			if (a[i]>s[top])
			{
				s[++top]=a[i];
				lmax[i]=std::max(lmax[i-1],top);
			}
			else
			{
				j=lower_bound(s+1,s+top,a[i]);
				*j=a[i];
				t=j-s;//注意指针类型会识别为long int!,必须强制转换
				lmax[i]=std::max(lmax[i-1],t);
			}
		}
		rmax[n]=1;//rmax[i]代表从n开始以i结尾的最大上升子序列长度
		top=0;
		memset(s,0,sizeof(s));
		s[++top]=a[n];
		for (i=n-1;i>=1;i--)//注意必须倒着找,不可以从头找降序
		{
			if (a[i]>s[top])
			{
				s[++top]=a[i];
				rmax[i]=max(rmax[i+1],top);
			}
			else
			{
				j=lower_bound(s+1,s+top,a[i]);
				*j=a[i];
				t=j-s;
				rmax[i]=max(rmax[i+1],t);
			}
		}
		ans=lmax[1]+rmax[2];
		for (i=2;i<=n-1;i++)
			ans=max(ans,lmax[i]+rmax[i+1]);
		cout<<ans<<endl;
	return 0;
}

AC2:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[1001],lmax[1001],rmax[1001];
int main()
{
	int n,i,ans,*j,s[1001];
		cin>>n;
		for (i=1;i<=n;i++)
			cin>>a[i];
		int top=0;
		lmax[1]=1;
		memset(s,0,sizeof(s));
		s[++top]=a[1];
		for (i=2;i<=n;i++)
		{
			if (a[i]>s[top])
			{
				s[++top]=a[i];
				lmax[i]=top;
			}
			else
			{
				j=lower_bound(s+1,s+top,a[i]);
				*j=a[i];
				if (lmax[i-1]>(j-s))
					lmax[i]=lmax[i+1];
				else 
					lmax[i]=j-s;
			}
		}
		rmax[n]=1;//rmax[i]代表从n开始以i结尾的最大上升子序列长度
		top=0;
		memset(s,0,sizeof(s));
		s[++top]=a[n];
		for (i=n-1;i>=1;i--)//注意必须倒着找,不可以从头找降序
		{
			if (a[i]>s[top])
			{
				s[++top]=a[i];
				rmax[i]=top;
			}
			else
			{
				j=lower_bound(s+1,s+top,a[i]);
				*j=a[i];
				if (rmax[i+1]>(j-s))
					rmax[i]=rmax[i+1];
				else 
					rmax[i]=j-s;
			}
		}
		ans=lmax[1]+rmax[2];
		for (i=2;i<=n-1;i++)
			if ((lmax[i]+rmax[i+1])>ans)
				ans=lmax[i]+rmax[i+1];
		cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/always_ease/article/details/80513122