题目描述
N位同学站成一排,音乐老师要请其中的(N−K)位同学出列使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K,他们的身高分别T1,T2,…,TK,则他们的身高满足T1<…<Ti>Ti+1>…>TK(1≤i≤K)(1≤i≤K) 。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
输入描述
输入的第一行是一个整数 N(2≤N≤100),表示同学的总数。第二行有n个整数,用空格分隔,第 i 个整数Ti(130≤Ti≤230)是第i位同学的身高(厘米)。
输出描述
输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
样例
输入
8 186 186 150 200 160 130 197 220
输出
4
题目分析
判断这是否是个dp问题 就要看他有没有最优子结构 很明显有
这是这个题的简图 必须画图 反正我不画图做不出来
题目是要一个有尖的“数列” 所以有个数很大 并且是要尖前面的位置成上升 后面的位置成下降
假设第i个数很大 那么就是前1-i里面求一个LIS最长上升子序列 后i-n个求最长下降子序列
当然这个地方不好求一个最长下降子序列 所以我们倒着从n-i求一个最长上升子序列
这里如果是求n-i的最长上升序列的话 我们要到(从)i+1这个位置
想想 如果当前为i 那么下一个位置就为i+1
最后比较求一个最大值
所以设置一个temp来存储 当前两个的值 但是这样会多算一个i
所以减去一个1
但是求的这个maxx是可以留多少人
题目中让求的是踢出多少人 所以要让n-maxx
输出即可
AC如下:
#include<iostream>
using namespace std;
const int N=105;
int qiandp[N],num[N],cnt,cmt,houdp[N];
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>num[i];
qiandp[i]=1;
houdp[i]=1;
}
// for(int i=1;i<=n;i++){
// qiandp[i]=1;
// houdp[i]=1;
// }
for(int i=1;i<=n;i++){
for(int j=1;j<=i-1;j++){
if(num[i]>num[j]&&qiandp[i]<qiandp[j]+1){
qiandp[i]=qiandp[j]+1;
}
}
}
for(int i=n;i>=1;i--){
for(int j=n;j>=i+1;j--){
if(num[i]>num[j]&&houdp[i]<houdp[j]+1){
houdp[i]=houdp[j]+1;
}
}
}
// for(int i=1;i<=n;i++){
// cout<<qiandp[i]<<" ";
// }
// cout<<endl;
// for(int i=n;i>=1;i--){
// cout<<houdp[i]<<" ";
// }
int maxx=0;
for(int i=1;i<=n;i++){
int temp=qiandp[i]+houdp[i]-1;
maxx=max(maxx,temp);
}
cout<<n-maxx;
//i为终点的最长上升子序列 以n为起点 以i为终点的最长上升子序列
return 0;
}