原题链接
题目大意
有
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<...<ai−1<ai>ai+1>...>an−1>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\}
1≤i≤nmax{llefti+rrighti−1}
上代码
#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 ∼