zoukankan      html  css  js  c++  java
  • NOIP 2004 T3 合唱队形(DP、最长上升/下降子序列)

    链接:https://ac.nowcoder.com/acm/contest/1082/C
    来源:牛客网

    题目描述

    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。

    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。

    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

    输入描述:

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

    输出描述:

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

    示例1

    输入

    8
    186 186 150 200 160 130 197 220

    输出

     4

    备注:

    对于50%的数据,保证有n<=20;
    对于全部的数据,保证有n<=100。

    我们把这个序列分成两部分来看,那么左边的部分是求一个最长上升子序列,右边是求一个最长下降子序列。

    那么我们就可以分别求一下整个序列的最长上升子序列和最长下降子序列,然后枚举中间点得到最多能留下来的人,然后就知道了答案。

    代码如下:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <set>
    10 #include <stack>
    11 #include <map>
    12 #include <math.h>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e5+10;
    17 using namespace std;
    18 
    19 int n;
    20 int A[105];
    21 int L[105];//L[i]表示从1到i这个点最长的上升子序列的长度
    22 int R[105];//R[i]表示从i到n这个点最长的下降子序列的长度即从n到i这个点最长的上升子序列的长度
    23 
    24 int main()
    25 {
    26     scanf("%d",&n);
    27     for(int i=1;i<=n;i++)
    28     {
    29         scanf("%d",&A[i]);
    30     }
    31     for(int i=1;i<=n;i++)//正着求最长上升子序列 
    32     {
    33         L[i]=1;
    34         for(int j=1;j<i;j++)
    35         {
    36             if(A[i]>A[j])
    37                 L[i]=max(L[i],L[j]+1);
    38         }
    39     }
    40     for(int i=n;i>=1;i--)//倒过来再求一遍最长上升子序列
    41     {
    42         R[i]=1;
    43         for(int j=n;j>i;j--)
    44         {
    45             if(A[i]>A[j])
    46                 R[i]=max(R[i],R[j]+1);
    47         }
    48     }
    49     int MAX=0;
    50     for(int i=1;i<=n;i++)//枚举中间点找最大值 
    51     {
    52         if(L[i]+R[i]-1>MAX)
    53         {
    54             MAX=L[i]+R[i]-1;
    55         }
    56     }
    57     printf("%d
    ",n-MAX);//减去最大值就是答案
    58     return 0;
    59 }
  • 相关阅读:
    境外支付宝接口对接--支付接口
    js bind
    css的input文本框的 propertychange、focus、blur
    字符流Reader和Writer
    对象流--对象的序列化
    输入流IS和输出流OS学习总结
    File文件的读写操作RandomAccessFile类
    File文件操作学习总结
    Map集合的便利学习总结
    Map集合学习总结
  • 原文地址:https://www.cnblogs.com/jiamian/p/11433505.html
Copyright © 2011-2022 走看看