合唱队形解题报告

2016-05-12   430——645

NOIP200407合唱队形

难度级别:A; 运行时间限制:1000ms; 运行空间限制:256000KB; 代码长度限制:2000000B

试题描述

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位同学的身高(厘米)。

输出

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

输入示例

8
186 186 150 200 160 130 197 220

输出示例

4

其他说明

数据范围:n<=100。

 

代码:

 #include<iostream>

 using namespace std;

 int b[],c[],a[];

 //    分别定义了三个数组:数组a(用来储存输入数据),数组b(用来存储从a[1]到a[n]的最大严格上升子序列长度),数组c(用来存储从a[n]到a[1]的最大严格下降子序列长度)

 int main()

 {

     int n,ans=,i,j;

     scanf("%d",&n);//输入

     for(i=;i<=n;i++) scanf("%d",&a[i]);

     b[]=;

 for(i=;i<=n;i++)

 //从a[2]开始求最大严格上升子序列长度

        {

         b[i]=;

         for(j=;j<i;j++)

             if(a[i]>a[j]) b[i]=max(b[i],b[j]+);

             //如果a[i]>a[j],则可能从a[1]到a[i]的最大严格上升子序列长度又增加了1。

     }

 c[n]=;

 //从a[n]开始求最大严格上升子序列长度

     for(i=n-;i>=;i--)

        {

         c[i]=;

         for(j=n;j>i;j--)

             if(a[i]>a[j]) c[i]=max(c[i],c[j]+);

             //如果a[i]<a[j],则可能从a[i]到a[n]的最大严格上升子序列长度又增加了1。

     }

     for(i=;i<=n;i++)

         if(b[i]+c[i]>ans) ans=b[i]+c[i];//更新答案

     printf("%d",n-ans+);//输出

 }

《合唱队形》这道题其实就是《求最长下降/上升子序列》的翻版。但如果用循环直接搜固然很难办,而且不知道会用多长时间,所以,简单动态规划的思想很容易办到。

b[i]=1;

这句赋值语句固然很好理解,每一个元素,也可以视为一个符合题意的子序列,不论是最长上升、最长下降。所以从a[1]

a[i]的符合题意的子序列必将有一个。比如有如下一组数。

b[1]  1,原因如上。

b[2]呢?如图,它显然比a[1]高,在执行如下语句时

for(j=1;j<i;j++)   if(a[i]>a[j])

j小于i,也就是2,目前符合条件的只有a[1]a[1]又通过了判断语句,它确实小于a[i],执行下一条语句:

b[i]=max(b[i],b[j]+1);

b[2]显然原来是1,当它和b[1]+1比时,1当然比2小,所以,b[2]自然就是2了。由此,这个方法只需要一维数组就行了。、

O(nlogn)的方法,将下次介绍。这样的方法的时间复杂度为O(n^2)


b[1]=1;

解决完了这个问题,这道题就非常简单了,先从下往上搜一遍最长上升子序列,代码如下:

for(i=2;i<=n;i++)

       {

        b[i]=1;

        for(j=1;j<i;j++)

            if(a[i]>a[j])
b[i]=max(b[i],b[j]+1);

}

再反着从上往下搜一下最长上升子序列:

这段代码一定就很好理解了:

for(i=1;i<=n;i++)

        if(b[i]+c[i]>ans) ans=b[i]+c[i];

一直更新ans,要求出队人数最少,自然要让保留人数最多。

最后输出n-ans+1

NOIP200407合唱队形+最长上升子序列O(n^2)详解的更多相关文章

  1. P1091 合唱队形 最长上升子序列

    思路:最长上升子序列 正着做一遍 倒着做一遍 然后 取最大值 #include<bits/stdc++.h> using namespace std; const int maxn=105 ...

  2. 最长上升子序列O(nlogn)算法详解

    最长上升子序列 时间限制: 10 Sec   内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...

  3. rnqoj-28-合唱队形-最长上升子序列

    想当年大一的时候,一个最长上升子序列的问题使得我的罚时上升了不少....当年还是图样啊 这道题目本质就是求最长上升子序列 #include<stdio.h> #include<str ...

  4. LeetCode 873. 最长的斐波那契子序列的长度 题目详解

    题目详情 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n >= 3 对于所有 i + 2 <= n,都有 X_i + X_{i+1} = X_ ...

  5. LCS最长公共子序列(最优线性时间O(n))

    这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...

  6. 洛谷 [p1439] 最长公共子序列 (NlogN)

    可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...

  7. 最长公共子序列 nlogn

    先来个板子 #include<bits/stdc++.h> using namespace std; , M = 1e6+, mod = 1e9+, inf = 1e9+; typedef ...

  8. NOIP 2004 T3 合唱队形(DP、最长上升/下降子序列)

    链接:https://ac.nowcoder.com/acm/contest/1082/C来源:牛客网 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队 ...

  9. 九度OJ 1131 合唱队形 -- 动态规划(最长递增子序列)

    题目地址:http://ac.jobdu.com/problem.php?pid=1131 题目描述: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合 ...

随机推荐

  1. 二级c程序设计题(1)

    原文:http://www.cnblogs.com/imaker/p/6120951.html 所属年份:2010.9;2011.3;2012.3;请编写函数fun,其功能是:找出2×M整型二维数组中 ...

  2. .NET基础加强,找工作之前可以看看这些............

    .NET基础知识加强: 1  变量命名规则:骆驼命名法:第一个字母小写之后的首字母大写,[对于方法名和类名首字母大写]→培养良好的命名规范. 2  构造函数:没有返回值,方法名和类名相同,每个类中都有 ...

  3. 5分钟弄懂Docker!

    http://www.csdn.net/article/2014-07-02/2820497-what%27s-docker 关注点:1.DOCKER和VM的架构区别 2.Docker 的容器利用了  ...

  4. for循环计数

    1.巧用for循环计数,将文件每10行写到另一个文件,每遍历一行i就加1 with open('/etc/passwd') as f1, open('/tmp/passwd','w') as f2: ...

  5. 串口通信类,WPF

    参考之前的资料,写了一个自己常用的串口类, 字符串发送类型用了两种方式,char[] 和byte[] : 数据接收也是采用两种 char[] 和byte[] 两种. 类代码贴出来: public cl ...

  6. 无法打开内核设备“\\.\Global\vmx86”: 系统找不到指定的文件。您在安装 VMware Workstation 后是否进行了重新引导?

    解决方法宿主机中执行如下命令重新启动: net start vmci net start vmx86 net start VMnetuserif sc config vmci=auto sc conf ...

  7. iOS添加自动更新的代码

    - (void)versionUpdate{ //获得当前发布的版本 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_ ...

  8. git客户端

    https://git-for-windows.github.io/ http://blog.csdn.net/shulianghan/article/details/18812279 自己的gith ...

  9. CPU虚拟化技术(留坑)

    留坑~~~ 不知道这个是这么实现的 CPU虚拟化技术就是单CPU模拟多CPU并行,允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率.虚 ...

  10. 1.Spring Web MVC有什么

    Spring Web MVC使用了MVC架构模式的思想,将web层进行职责解耦. 同样也是基于请求驱动的,也就是使用请求-响应模型.它主要包含如下组件: DispatcherServlet :前端控制 ...