NOIP200407合唱队形+最长上升子序列O(n^2)详解
合唱队形解题报告
2016-05-12 4:30——6:45
|
NOIP200407合唱队形 |
|
难度级别:A; 运行时间限制:1000ms; 运行空间限制:256000KB; 代码长度限制:2000000B |
|
试题描述 |
|
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 |
|
输入 |
|
第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。 |
|
输出 |
|
包括一行,这一行只包含一个整数,就是最少需要几位同学出列。 |
|
输入示例 |
|
8 |
|
输出示例 |
|
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)详解的更多相关文章
- P1091 合唱队形 最长上升子序列
思路:最长上升子序列 正着做一遍 倒着做一遍 然后 取最大值 #include<bits/stdc++.h> using namespace std; const int maxn=105 ...
- 最长上升子序列O(nlogn)算法详解
最长上升子序列 时间限制: 10 Sec 内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...
- rnqoj-28-合唱队形-最长上升子序列
想当年大一的时候,一个最长上升子序列的问题使得我的罚时上升了不少....当年还是图样啊 这道题目本质就是求最长上升子序列 #include<stdio.h> #include<str ...
- LeetCode 873. 最长的斐波那契子序列的长度 题目详解
题目详情 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n >= 3 对于所有 i + 2 <= n,都有 X_i + X_{i+1} = X_ ...
- LCS最长公共子序列(最优线性时间O(n))
这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...
- 洛谷 [p1439] 最长公共子序列 (NlogN)
可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...
- 最长公共子序列 nlogn
先来个板子 #include<bits/stdc++.h> using namespace std; , M = 1e6+, mod = 1e9+, inf = 1e9+; typedef ...
- NOIP 2004 T3 合唱队形(DP、最长上升/下降子序列)
链接:https://ac.nowcoder.com/acm/contest/1082/C来源:牛客网 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队 ...
- 九度OJ 1131 合唱队形 -- 动态规划(最长递增子序列)
题目地址:http://ac.jobdu.com/problem.php?pid=1131 题目描述: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合 ...
随机推荐
- HTML标签的改变
/*这些都是前端面试中经常考到的内容,必须要掌握的*/ 一.新的文档类型声明(DTD) 1.HTML5的DTD声明为:<!doctype html>或者<!DOCTYPE html& ...
- PySe-001-基础环境配置(MacOX)
Python 是一种面向对象.解释型计算机程序设计语言,其源代码同样遵循 GPL(GNU General Public License)协议.Python语法简洁而清晰,具有丰富和强大的类库.由于Py ...
- 【转】android Graphics(四):canvas变换与操作
android Graphics(四):canvas变换与操作 分类: 5.andriod开发2014-09-05 15:05 5877人阅读 评论(18) 收藏 举报 目录(?)[+] 前言 ...
- channelartlist添加栏目链接
{dede:channelartlist} <a href='{dede:field name='typeurl'/}'></a> {/dede:channelartlist}
- Virtio:针对 Linux 的 I/O 虚拟化框架
Virtio:针对 Linux 的 I/O 虚拟化框架 --http://www.ibm.com/developerworks/cn/linux/l-virtio/#ibm-pcon 使用 KVM 和 ...
- 56个睿智帅气貌美的CTO大牛陪你叨逼叨
技术领域门槛高,苦读十年有时不如大牛一指点 可CTO级别的大牛何处找? 别急,别急 他们1月12日都去参加APICloud新品发布会了! (没图说啥子) 各路大牛们云集,不仅是为APICloud新品发 ...
- 私有IP地址范围
私有IP地址范围 有一部分的地址专门是用于内网的地址,包括: A类中 10.0.0.0/8 B类中 172.16.0.0/12 ~ 172.31.0.0/12 C类中 192.168.0.0/16 这 ...
- MongoDB Map Reduce
介绍 Map-Reduce是一种计算模型,简单的说就是将大批量的工作分解(MAP)执行,然后再将结果合并成最终结果(REDUCE). MongoDB提供的Map-Reduce非常灵活,对于大规模数据分 ...
- MongoDB时间类型
mongdb时间类型 Date() 显示当前的时间 new Date 构建一个格林尼治时间 可以看到正好和Date()相差8小时,我们是+8时区,也就是时差相差8,所以+8小时就是系统当前时间 I ...
- UIKit结构图