2004年分区联赛提高组之三 合唱队形(dp)

来源:互联网 发布:linux自动挂载硬盘 编辑:程序博客网 时间:2024/05/16 15:15

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

Description

  N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 
  合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...Ti+1>…>TK(1<=i<=K)。 
  你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。 

Input

输入的第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。

Output

  输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

Sample Input

8186 186 150 200 160 130 197 220

Sample Output

4
分析:从左往右做一次最长不下降序列,从右往左做一次最长不下降序列,显然最后的k=max{b[i]+c[i]}-1,最后n-k即为所求。
          最长不下降序列方程:f[i]=max(f[j]+1)  (1<=i<=n,1<=j<i,a[j]>a[i])
代码
#include <cstdio>using namespace std;int a[200],b[200],c[200];int main(){int n;scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d",&a[i]);for (int i=1;i<=n;i++){b[i]=1;for (int j=1;j<=i-1;j++)if ((a[i]>a[j])&&(b[j]+1>b[i]))b[i]=b[j]+1;}for (int i=n;i>=1;i--){c[i]=1;for (int j=i+1;j<=n;j++)if ((a[j]<a[i])&&(c[j]+1>c[i]))c[i]=c[j]+1;}int max=0;for (int i=1;i<=n;i++)if (b[i]+c[i]>max)max=b[i]+c[i];printf("%d",n-max+1);return 0;}
原创粉丝点击