SSL1041 2004年分区联赛提高组之三 合唱队形


原题链接

外网进不去

题目大意

n n n个人,给出他们的身高,要除去若干人,使得剩下的人的身高构成一个单峰序列,单峰序列就是 a 1 < a 2 < . . . < a i − 1 < a i > a i + 1 > . . . > a n − 1 > a n a_1<a_2<...<a_{i-1}<a_i>a_{i+1}>...>a_{n-1}>a_n a1<a2<...<ai1<ai>ai+1>...>an1>an
请求出在满足要求的情况下,最少要去掉多少人。
S a m p l e \mathbf{Sample} Sample I n p u t \mathbf{Input} Input

8
186 186 150 200 160 130 197 220

S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output

4

H i n t & E x p l a i n \mathbf{Hint\&Explain} Hint&Explain
去掉第1,2,7,8号人,剩下人组成的序列为150 200 160 130,这是一个以200为峰的结果。
注意:方案可能有很多种,只要输出去掉多少人就可以了。

解题思路

先从前到后做一遍最长上升子序列,计为 l l e f t lleft lleft
再从后到前做一遍最长上升子序列,计为 r r i g h t rright rright
然后枚举每一个人作为峰顶,将 l l e f t lleft lleft中以他为终点的最长上升子序列和 r r i g h t rright rright里的加在一起,再 − 1 -1 1去他自己的重,取最大值就是答案,即答案为:
max ⁡ 1 ≤ i ≤ n { l l e f t i + r r i g h t i − 1 } \max_{1\le i\le n}\{lleft_i+rright_i-1\} 1inmax{llefti+rrighti1}

上代码

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

int n,a[101],lleft[101],rright[101];

int main()
{
	cin>>n;
	for(int i=1; i<=n; i++) cin>>a[i];
	lleft[1]=rright[n]=1;
	for(int i=2; i<=n; i++)
	{
		int maxx=0;
		for(int j=i-1; j>=1; j--)
		{
			if(a[j]<a[i]&&maxx<lleft[j]) maxx=lleft[j];
		}
		lleft[i]=maxx+1;
	}
	for(int i=n-1; i>=1; i--)
	{
		int maxx=0;
		for(int j=i+1; j<=n; j++)
		{
			if(a[i]>a[j]&&maxx<rright[j]) maxx=rright[j];
		}
		rright[i]=maxx+1;
	}
	int maxx=0;
	for(int i=1; i<=n; i++)
	{
		if(lleft[i]+rright[i]-1>maxx) maxx=lleft[i]+rright[i]-1;
	}
	cout<<n-maxx<<endl;
	return 0;
}

完美切题 ∼ \sim

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值