1065: 合唱队形(最长上升,下降子序列)

原题链接

1065: [视频]动态规划入门(一维一边推3:合唱队形)
时间限制: 1 Sec 内存限制: 128 MB
提交: 339 解决: 168
[提交][状态][讨论版]
题目描述
【题目】
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,
他们的身高分别为T1,T2,…,TK,则他们的身高满足 T1 < T2 …< Ti > Ti+1 > … >TK(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
先求最长上升子序列,再求最长下降子序列,当前位置两个数的和最大时,出队列的人最少。

#include
#include
using namespace std;
int num[1005],ans[1005],ans2[1005];
int n;
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        cin>>num[i];
        ans2[i]=ans[i]=1; 
    }
    for (int i=2;i<=n;i++)//最长上升子序列 
    {
        for (int j=i-1;j>=ans[i];j--)
        {
            if (num[i]>num[j])
            {
                ans[i]=max(ans[j]+1,ans[i]);
            }
        }
    }
    for (int i=n-1;i>=1;i--)//最长下降子序列 
    {
        for (int j=i+1;j<=n;j++)
        {
            if (num[i]>num[j])
            ans2[i]=max(ans2[i],ans2[j]+1);
        }
    }
    for (int  i=1;i<=n;i++)
    ans[i]+=ans2[i]; 
    cout<1,ans+n+1)+1;
    return 0;
}

你可能感兴趣的:(动态规划)