【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]
以题写模板。
写了两个:n^2版本与nlogn版本
P1091 合唱队形
题目描述
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
输入输出格式
输入格式:
输入文件chorus.in的第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。
输出格式:
输出文件chorus.out包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
输入输出样例
8
186 186 150 200 160 130 197 220
4
说明
对于50%的数据,保证有n<=20;
对于全部的数据,保证有n<=100。
LIS,即最长上升子序列。
n^2算法:
状态:f[i]表示前i个数(包含第i个)最长上升子序列长度
转移方程:f[i] = max(f[j]),其中1 <= j < i
初始状态:f[i] = 1,其中1 <= i <= n
这个题目很显然正着一遍上升,倒着一遍上升。
正确解法:把所有的点扫一遍,结果为 人数 - (同一个点的正着上升与倒着上升之和减去1(因为加了两次当前这个点)) 的最小值。
错误解法:把所有的点扫一遍,结果为 人数 - (第i个人正着上升与第i+1倒着上升之和))最小值 因为倘若num[i] > num[i+1],可能第i -1个人正着上升与第i个人倒着上升之和才是正解
反例数据(洛谷上的一组):
100
225 176 227 185 171 188 204 152 144 210 190 188 140 150 213 178 177 188 217 154 178 226 217 181 171 206 130 165 135 205 142 180 228 160 179 230 208 196 217 225 180 204 137 149 139 158 133 169 168 145 175 161 154 230 222 210 174 130 186 207 169 192 193 194 223 138 136 173 207 180 218 201 183 190 218 176 149 191 156 206 140 213 151 179 219 202 149 182 148 156 156 179 142 212 135 133 183 201 219
(有耐心的同学自己看吧。。反正我知道放了也是白放。。
nlogn的算法:
f[i]表示最长公共子序列长度为i的子序列末尾数的最小值,初始为正无穷大(0x3f3f3f3f)
可知f[i]一定是单调的
对于num[i],只需要在f中找出大于他的数中最小的,替换掉,替换的这个数的下标就是第i个数的最长公共子序列长度。
手动模拟效果更佳。
n^2版本:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
const int INF = 999999999;
const int MAXN = 100 + 10;
inline int read()
{
int x = 0;char ch = getchar();char c = ch;
while(ch > '9' || ch < '0')c = ch,ch = getchar();
while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
if(c == '-')return -1 * x;
return x;
} int lis[MAXN],lds[MAXN],num[MAXN],n,ans,len; int main()
{
n = read();
for(int i = 1;i <= n;i ++)
{
num[i] = read();
} for(int i = 1;i <= n;i ++)
{
lis[i] = 1;
for(int j = 1;j <= i - 1;j ++)
{
if(num[j] < num[i])lis[i] = max(lis[i], lis[j] + 1);
}
} for(int i = n;i >= 1;i --)
{
lds[i] = 1;
for(int j = n;j >= i + 1;j --)
{
if(num[j] < num[i])lds[i] = max(lds[i], lds[j] + 1);
}
} ans = INF;
for(int i = 1;i <= n;i ++)
{
ans = min(ans, n - lis[i] - lds[i]);
}
printf("%d", ans);
return 0;
}
nlogn版本:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
const int INF = 999999999;
const int MAXN = 100 + 10;
inline int read()
{
int x = 0;char ch = getchar();char c = ch;
while(ch > '9' || ch < '0')c = ch,ch = getchar();
while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
if(c == '-')return -1 * x;
return x;
} int lis[MAXN],lds[MAXN],f[MAXN],num[MAXN],n,ans,len; int main()
{
n = read();
for(int i = 1;i <= n;i ++)
{
num[i] = read();
} memset(f, 0x3f, sizeof(f));
f[1] = num[1];lis[1] = 1;
for(int i = 2;i <= n;i ++)
{
f[lis[i] = std::lower_bound(f + 1, f + 1 + n, num[i]) - f] = num[i];
} memset(f, 0x3f, sizeof(f));
f[1] = num[n];lds[n] = 1;
for(int i = n - 1;i >= 1;i --)
{
int temp = std::lower_bound(f + 1,f + 1 + n, num[i]) - f;
lds[i] = temp;
f[temp] = num[i];
} ans = INF;
for(int i = 1;i <= n ;i ++)
{
ans = min(ans, n - lis[i] - lds[i] + 1);
}
printf("%d", ans);
return 0;
}
【模板】LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]的更多相关文章
- 洛谷P1091 [NOIP2004 提高组] 合唱队形
本题是一个简单的 LIS(最长上升子序列)问题 只是要求俩次最长上子序列而已 很容易的 首先由于是最长上升子序列 所以朴素法的动态规划表达式为 f[i] = max( f[i] , f[ ...
- P1091 [NOIP2004 提高组] 合唱队形
题目描述 $N$位同学站成一排,音乐老师要请其中的$\left ( N-K\right )$位同学出列,使得剩下的$K$位同学排成合唱队形. 合唱队形是指这样的一种队形:设$K$位同学从左到右依次编号 ...
- 洛谷P1508 Likecloud-吃、吃、吃 [2017年4月计划 动态规划10]
P1508 Likecloud-吃.吃.吃 题目背景 问世间,青春期为何物? 答曰:“甲亢,甲亢,再甲亢:挨饿,挨饿,再挨饿!” 题目描述 正处在某一特定时期之中的李大水牛由于消化系统比较发达,最近一 ...
- 【模板】Tarjan缩点,强连通分量 洛谷P2341 [HAOI2006]受欢迎的牛 [2017年6月计划 强连通分量01]
P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的 ...
- 洛谷P6033 [NOIP2004 提高组] 合并果子 加强版 (单调队列)
数据加强了,原来nlogn的复杂度就不行了...... 首先对原来的n个数排序(注意不能用快排),因为值域是1e5,所以可以开桶排序,开两个队列,一个存原来的n个数(已经满足单增),另一队列存两两合并 ...
- 洛谷P1368 均分纸牌(加强版) [2017年6月计划 数论14]
P1368 均分纸牌(加强版) 题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,纸牌总数必为 N 的倍数.可以在任一堆上取1张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取 ...
- 洛谷P2912 [USACO08OCT]牧场散步Pasture Walking [2017年7月计划 树上问题 01]
P2912 [USACO08OCT]牧场散步Pasture Walking 题目描述 The N cows (2 <= N <= 1,000) conveniently numbered ...
- 洛谷P1029 最大公约数和最小公倍数问题 [2017年6月计划 数论02]
P1029 最大公约数和最小公倍数问题 题目描述 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1 ...
- 洛谷P1514 [NOIP2010提高组T4]引水入城
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城 ...
随机推荐
- MYSQL获取同时关注了某两个(或者N个)用户的用户
使用redis的set类型数据的话会比较容易,但是业务场景就是在mysql里面,因此也需要思考解决方法 表结构: CREATE TABLE `table_name` ( `id` ) unsigned ...
- 19-10-26-Night-D
压表的技巧. ZJ一下: T1,考试不会哈夫曼树只压到$1MB$最后截掉了一部分. T2,直接暴力丢上去.$\Theta(N+\sqrt{N}\log N)$ T3,现场码出左右旋然后就不会了$QAQ ...
- CobaltStrike与Metasploit实战联动
前言 CobalStrike 与 Metasploit 均是渗透利器,各有所长.前者更适合做稳控平台,后者则更擅长内网各类探测搜集与漏洞利用.两者更需要灵活的联动,各自相互依托,从而提升渗透的效率. ...
- vuex mutation,action理解
1. 在store中分别注册mutation和action,action中用commit同步调用mutation来执行修改state,但是在组件中则使用dispatch异步调用action 2. 通俗 ...
- 简单数论 | Day3 部分题解
A - The Euler function 来源:HDU 2824 计算[a,b]区间内的整数的欧拉函数值,需要掌握单个欧拉函数和函数表的使用. #include <iostream> ...
- myeclipse工程更新后java图标变为空心的解决办法
今天用svn更新了工程发现目录结构改变了,同时所有的java文件的图标变成了空心的.解决办法如下 1.右键单击工程目录名,选择properties. 2.选择java bulid path,正常的应该 ...
- #iOS问题记录# 频繁触发viewDidLayoutSubviews的问题
问题描述: 最近使用给Flutter团队写view组件的时候,出现了触发Widget的频繁build的问题. 问题排查: Flutter的同事提到在flutter层,是因为 updateViewpor ...
- PostgreSQL的架构
是最先进的数据库.他的第一个版本在1989年发布,从那时开始,他得到了很多扩展.根据db-enginers上的排名情况,PostgreSQL目前在数据库领域排名第四. 本篇博客,我们来讨论一下Post ...
- js的深复制与浅复制
什么是深复制和浅复制? 深复制和浅复制的概念只存在于对象array和数组obj上. 浅复制是:模糊复制,就是不管对方是字符串类型还是引用类型都通通复制过来.结果两个变量的内容会同时变化. 深复制是:有 ...
- 转: V4L2驱动程序架构
源地址:http://blog.chinaunix.net/uid-26101960-id-3297657.html 1 V4L2简介 video4linux2(V4L2)是Linux内核中关于视频设 ...