题目

【题目描述】
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
【输入格式】
输入文件chorus.in的第一行是一个整数N,表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti是第i位同学的身高(厘米)。
【输出格式】
输出文件chorus.out包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
【样例输入】
8
186 186 150 200 160 130 197 220
【样例输出】
4
【数据规模】
对于50%的数据,保证有n<=200;
对于100%的数据,保证有n<=20000,1<=Ti<=1000000。

解析

该题本身平淡无奇,只是一个标准的LIS动态规划。但是!该题扩大了数据范围!
使得本来O(n2)的时间复杂度过不了,于是只有优化(关键是我考试时没怎么注意)。
这里便会有二分查找的优化方法。

思路

枚举中间的人i,以他为终点正向和倒向求两次LIS,用l[i]和r[i]分别表示以i结尾LIS长度。然后ans = n - l[i] + r[i] + 1;

注意到N <= 20000,所以必须使用logN的算法求LIS
使用d[]临时存储LIS,依次将序列中的数a[i]按以下条件加入d[]中:如果a[i] > d[len](d[len]是d[]中的最后一个数),则d[++len] = a[i],否则在d[]中找第一个比a[i]**大或等(必须取到=,否则相同的数将不被替换,而是替换成了第一个比它大的数** )的数,将其替换,这样做的目的是使d[]更有可能成为一个更长的序列。我们注意到d[]是一个递增的序列,则在完成查找时可使用二分的方法。
注意在这个过程中存储l[i]和r[i]

代码

#include<iostream>
#include<cstring>
using namespace std; int a[],l[],r[],rem[];
int n; int main()
{
freopen("chorus.in","r",stdin);
freopen("chorus.out","w",stdout); cin>>n;
for(int i=;i<=n;i++) cin>>a[i]; int len=;
for(int i=;i<=n;i++)
{
if(a[i]>rem[len])
{
rem[++len]=a[i];
l[i]=len;
}
else
{
int left=,right=len;
while(left<right)
{
int mid=(left+right)/;
if(rem[mid]>=a[i])right=mid;
//此处必须取到=,否则相同的数将不被替换,而是替换成了第一个比它大的数
else left=mid+;
}
rem[left]=a[i];
l[i]=left;
}
} memset(rem,,sizeof(rem)); len=;
for(int i=n;i>=;i--)
{ if(a[i]>rem[len])
{
rem[++len]=a[i];
r[i]=len;
}
else
{
int left=,right=len;
while(left<right)
{
int mid=(left+right)/;
if(rem[mid]>=a[i])right=mid;
//此处必须取到=,否则相同的数将不被替换,而是替换成了第一个比它大的数
else left=mid+;
}
rem[left]=a[i];
r[i]=left;
}
} int maxx=;
for(int i=;i<=n;i++)
maxx=max(maxx,l[i]+r[i]-); cout<<n-maxx<<endl;
return ;
}

【题解】合唱队形——LIS坑爹的二分优化的更多相关文章

  1. 合唱队形(LIS)

    合唱队形    OpenJ_Bailian - 2711 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同 ...

  2. P1091 合唱队形题解(洛谷,动态规划LIS,单调队列)

    先上题目 P1091 合唱队形(点击打开题目) 题目解读: 1.由T1​<...<Ti​和Ti​>Ti+1​>…>TK​可以看出这题涉及最长上升子序列和最长下降子序列 2 ...

  3. POJ 3903:Stock Exchange(裸LIS + 二分优化)

    http://poj.org/problem?id=3903 Stock Exchange Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  4. 二分优化lis和STL函数

    LIS:最长上升子序列: 这个题我们很显然会想到使用dp, 状态设计:dp[i]代表以a[i]结尾的LIS的长度 状态转移:dp[i]=max(dp[i], dp[j]+1) (0<=j< ...

  5. (LIS) P1091 合唱队形 洛谷

    题目描述 NN位同学站成一排,音乐老师要请其中的(N-KN−K)位同学出列,使得剩下的KK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K1,2,…,K,他 ...

  6. HDU 1025 LIS二分优化

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: ...

  7. 新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛)C 勤奋的杨老师【DP/正反LIS/类似合唱队形】

    链接:https://www.nowcoder.com/acm/contest/116/C 来源:牛客网 题目描述 杨老师认为他的学习能力曲线是一个拱形.勤奋的他根据时间的先后顺序罗列了一个学习清单, ...

  8. 二分优化的lis

    /*此题为一个女大佬教我的,%%%%%%%%%%%%*/ 题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为 ...

  9. HDU 1025:Constructing Roads In JGShining's Kingdom(LIS+二分优化)

    http://acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Problem Des ...

随机推荐

  1. vim环境下空格和tab键互换

    对于已保存的文件,可以使用下面的方法进行空格和TAB的替换 TAB替换为空格::set ts=4:set expandtab:%retab! 空格替换为TAB::set ts=4:set noexpa ...

  2. Java类的使用

    在一个Java文件中写两个类:一个基本的类,一个测试类.注意:文件名称和测试类名称一致. 如何使用呢?创建对象使用.如何创建对象呢?格式:类名 对象名 = new 类名(); Student s = ...

  3. SK-learn实现k近邻算法【准确率随k值的变化】-------莺尾花种类预测

    代码详解: from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split fr ...

  4. php下载各种编辑器输出的内容到word中展示

    <?php/** * Created by PhpStorm. * User: 工作 * Date: 2018/1/11 * Time: 12:02 */ //连接数据库$dsn = " ...

  5. Task Scheduler API Error 80041318

    https://stackoverflow.com/questions/42307917/task-scheduler-api-error-80041318/42462235#42462235 Hi ...

  6. java中的daemon thread

    java中的daemon thread java中有两种类型的thread,user threads 和 daemon threads. User threads是高优先级的thread,JVM将会等 ...

  7. mac OS 安装配置Nginx服务器

    系统环境 安装工具 Homebrew软件包管理器 :<mac OS 安装 Homebrew软件包管理器>https://blog.csdn.net/weixin_41791279/arti ...

  8. centos 7.0运行docker出现内核报错解决方法

    目前我这里docker是运行在centos 7.0系统里,使用1.5版本docker,最近一台服务器总是不定期死机,通过查看日志发现属于内核bug导致,报错信息如下 1 2 3 4 5 6 7 8 9 ...

  9. C++ 模板(template) 的定义

    定义: 模板(template)是实现代码重用机制的一种工具,它可以实现类型参数化,把类型定义为参数(模板元编程),从而实现了真正的代码可重用性. 模板是用来批量生成功能和形式都几乎相同的代码的.编译 ...

  10. CUDA编程学习相关

    1. CUDA编程之快速入门:https://www.cnblogs.com/skyfsm/p/9673960.html 2. CUDA编程入门极简教程:https://blog.csdn.net/x ...