题目描述

链接:https://ac.nowcoder.com/acm/problem/16664
来源:牛客网

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

题目思路

题目重点:如何找到最适合的数列峰位?
对身高数组a[]进行遍历,对于当前位置a[i],将a[]分为前后两部分;对前一部分找包含a[i]的最长递增子序列长度l1[i],对后一部分找包含a[i]的最长递减子序列长度l2[i]。

完整代码

#include<bits/stdc++.h>
using namespace std;
int n[110];
int l1[110], l2[110];

int main()
{
    int a;
    scanf("%d",&a);
    int i=1;
    while(scanf("%d",&n[i++])!=EOF);
    for(int i=1;i<=a;i++)
    {
        l1[i] = 1;
        l2[i] = 1;
    }
    for(int i=2;i<=a;i++)
    {
        for(int j=1;j<i;j++)
        {
            if(n[i]>n[j])
            {
                l1[i] = max(l1[i], l1[j]+1);
            }
        }
    }
    for(int i=a-1;i>0;i--)
    {
        for(int j=a;j>i;j--)
        {
            if(n[i]>n[j])
            {
                l2[i] = max(l2[i], l2[j]+1);
            }
        }
    }
    int max = -1;
    for(int k=1;k<=a;k++)
    {
        if(max < l1[k]+l2[k]-1)
        {
            max = l1[k]+l2[k]-1;
        }
    }
    printf("%d\n", a-max);
}

反思

本题思路简单,但是一直出错的原因是在求l1[i]时,使用了求前i个的最长递增子序列的思路,没有注意到必须要包含a[i]元素。一定要注意两种想法之间的对比。