• 洛谷1091合唱队形


    题目描述

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

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

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

    输入输出格式

    输入格式:

     

    共二行。

    第一行是一个整数N(2N100),表示同学的总数。

    第二行有n个整数,用空格分隔,第i个整数(130Ti230)是第ii位同学的身高(厘米)。

     

    输出格式:

     

    一个整数,最少需要几位同学出列。

     

    输入输出样例

    输入样例#1: 复制
    8
    186 186 150 200 160 130 197 220
    
    输出样例#1: 复制
    4
    

    说明

    对于50%的数据,保证有n20;

    对于全部的数据,保证有n100。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 int i,j,n,a[105],f[2][105],ans;
     7 int main()
     8 {
     9     scanf("%d",&n);
    10     for(i = 1;i <= n;i++)
    11     {
    12         scanf("%d",&a[i]);
    13     }
    14     a[0] = 0;
    15     for(i = 1;i <= n;i++)//从1到n求最长列 
    16     {
    17         for(j = 0;j <= i;j++)
    18         {
    19             if(a[i] > a[j])
    20             f[0][i] = max(f[0][i],f[0][j] + 1);
    21         }
    22     }
    23     a[n + 1] = 0;
    24     for(i = n;i >= 1;i--)//从n到1求最长列 
    25     {
    26         for(j = n + 1;j > i;j--)
    27         {
    28             if(a[i] > a[j])
    29             f[1][i] = max(f[1][i],f[1][j] + 1);
    30         }
    31     }
    32     for(i = 1;i <= n;i++)
    33     {
    34         ans = max(f[0][i] + f[1][i] - 1,ans);//枚举Ti,从1到Ti的最长列+从TK到Ti的最长列- 1(Ti被加了两次)
    35     }
    36     printf("%d",n - ans);
    37     return 0;
    38  } 

    *****显然这个是一个区间DP呦,从前往后求最长上升序列,然后求从后往前求最长上升序列,最后枚举中间人的位置求出答案,吼吼吼

  • 相关阅读:
    在消息框中添加帮助按钮
    如何隐藏一个窗口在任务栏
    不透明的形式在c#中
    实现观察者模式在一个非常简单的例子
    更新使用回调模态对话框的内容
    检查Windows应用程序的现有实例,并设置MDI子程序的MDI父窗体
    更改对话框内容的简单方法
    MSIUninstaller.exe(控制台应用程序)
    启用或禁用控制更有效的和有效的方式
    一个c++ OCX,用于在应用程序的任何窗口上绘图
  • 原文地址:https://www.cnblogs.com/rax-/p/9885642.html
Copyright © 2020-2023  润新知