UVA1471( LIS变形)
这是LIS的变形,题意是求一个序列中去掉某个连续的序列后,能得到的最长连续递增序列的长度。
用DP的解法是:吧这个序列用数组a来记录,再分别用两个数组f记录以i结尾的最长连续递增序列的长度,g[i]记录以i开头的最长连续递增序列。然后像求DP求LIS一样遍历整个序列求出i前面所有小于a[i]的元素中以该元素结尾的最长序列f[j], 那么 dp[i] = g[j] + f[i], 这样时间复杂度为O(n^2)。
由于和普通的LIS类似,所以可以利用LIS的优化方法把该题的时间复杂的优化到O(nlogn)。方法仍是利用一个数组d[i]记录长度为 i 的连续递增序列的最后一个元素的最小值,显然该序列是单调递增的,所以上面红色字体的操作可以通过二分查找直接得到f[j]的值,进而得到一个可行的长度ans, 然后更新数组d即可,更新的方法是如果以a[i]小于数组d中记录的与a[i]长度相同的序列的最后一个元素的值,那么把这个值改为a[i], 即 d[f[i]] = min(a[i], d[f[i]]); 最终ans的最大值即为答案。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int MAXN = ;
const int INF = << ;
int a[MAXN], f[MAXN], g[MAXN], d[MAXN]; int main()
{
int t, n, i;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(i = ; i <= n; i++)
scanf("%d", &a[i]); f[] = ;
for(i = ; i <= n; i++)
if(a[i] > a[i - ])
f[i] = f[i - ] + ;
else
f[i] = ; g[n] = ;
for(i = n - ; i > ; i--)
if(a[i] < a[i + ])
g[i] = g[i + ] + ;
else
g[i] = ; int ans = ;
for(i = ; i <= n; i++)
d[i] = INF; //d[i]的值全部赋值为INF,方便二分查找和更新d[i]
for(i = ; i <= n; i++)
{
int len = (lower_bound(d + , d + + i, a[i]) - (d + )) + g[i];
ans = max(len, ans);
d[f[i]] = min(a[i], d[f[i]]);
}
printf("%d\n", ans);
}
return ;
}
另外附上LIS的代码:(时间复杂度为O(nlogn)
#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std;
const int MAXN = ;
const int INF = << ;
int b[MAXN];
int main()
{
int n, i, tem;
while(scanf("%d", &n) != -)
{
for(i = ; i <= n + ; i++)
b[i] = INF;
for(i = ; i < n; i++)
{
scanf("%d", &tem);
int pos = lower_bound(b, b+i+, tem) - b; //二分查找tem要插入的位置
b[pos] = tem; //更新单调栈
}
for(i = ; b[i] != INF; i++); //求单调栈的长度
printf("%d\n", i);
}
}
UVA1471( LIS变形)的更多相关文章
- 九度 1557:和谐答案 (LIS 变形)
题目描述: 在初试即将开始的最后一段日子里,laxtc重点练习了英语阅读的第二部分,他发现了一个有意思的情况.这部分的试题最终的答案总是如下形式的:1.A;2.C;3.D;4.E;5.F.即共有六个空 ...
- hdu 1087(LIS变形)
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- UVA 437 巴比伦塔 【DAG上DP/LIS变形】
[链接]:https://cn.vjudge.net/problem/UVA-437 [题意]:给你n个立方体,让你以长宽为底,一个个搭起来(下面的立方体的长和宽必须大于上面的长和宽)求能得到的最长高 ...
- UVa 1471 (LIS变形) Defense Lines
题意: 给出一个序列,删掉它的一个连续子序列(该子序列可以为空),使得剩下的序列有最长的连续严格递增子序列. 分析: 这个可以看作lrj的<训练指南>P62中讲到的LIS的O(nlogn) ...
- hdu5773--The All-purpose Zero(LIS变形)
题意:给一个非负整数的数列,其中0可以变成任意整数,包括负数,求最长上升子序列的长度. 题解:LIS是最简单的DP了,但是变形之后T^T真的没想到.数据范围是10^5,只能O(nlogn)的做法,所以 ...
- HDU-1160.FatMouse'sSpeed.(LIS变形 + 路径打印)
本题大意:给定一定数量的数对,每个数保存着一只老鼠的质量和速度,让你求出一个最长序列,这个序列按照质量严格递增,速度严格递减排列,让你输出这个序列的最长长度,并且输出组成这个最长长度的序列的对应的老鼠 ...
- POJ 1836-Alignment(DP/LIS变形)
Alignment Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 13465 Accepted: 4336 Descri ...
- poj 1836 LIS变形
题目链接http://poj.org/problem?id=1836 Alignment Time Limit: 1000MS Memory Limit: 30000K Total Submiss ...
- P1481 魔族密码(LIS变形)
题目描述(题目链接:https://www.luogu.org/problem/P1481) 风之子刚走进他的考场,就…… 花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花) 风之 ...
随机推荐
- JAVA I/O使用方法(转)
下面四张图表明了类之间的继承关系,其中红色.加粗的类名是常用的类. 常用转换 FileReader——>BufferedReader BufferedReader in= new Buffere ...
- 如果有三个Bool型变量,请写出一程序得知其中有2个以上变量的值是true
下面这篇文章是从StackOverflow来的.LZ面试的时候遇到了一道面试题:“如果有三个Bool型变量,请写出一程序得知其中有2个以上变量的值是true”,于是LZ做了下面的这样的程序: bool ...
- LBYL与EAFP两种防御性编程风格
检查数据可以让程序更健壮,用术语来说就是防御性编程. 检查数据的时候,有这样的两种不同的风格. LBYL:Look Before You Leap EAFP:It's Easier to Ask ...
- [LeetCode][Python]Regular Expression Matching
# -*- coding: utf8 -*-'''https://oj.leetcode.com/problems/regular-expression-matching/ Implement reg ...
- CVTE 嵌入式软件工程师 二面
昨天晚上收到了二面的通知,激动啊-第二天提前20分钟到达指定地点,然后一起做大巴去到CVTE总部,发现笔试刷掉的人好像并不是很多.我们一下车被带到了公司的电影院,听演唱会.呵呵,挺有意思的,有一个漂亮 ...
- Android @+id与@id的区别
Android中的组件需要用一个int类型的值来表示,这个值也就是组件标签中的id属性值.id属性只能接受资源类型的值,也就是必须以@开头的值,例如,@id/abc.@+id/xyz等. 如果在@ ...
- android 强制设置横屏 判断是横屏还是竖屏
判断activity 是横屏还是竖屏 方法 1: //根据设备配置信息 Configuration cf= this.getResources().getConfiguration(); //获取设 ...
- javascript 工作必知(四) 类型转换
string和number boolean javascript 类型会根据赋值的进行转成相应的类型. var str = ""; alert(typeof (str));//st ...
- 1.一步一步学c#(一):.NET体系结构(知识点)
一.C#和.NET关系 1. 首先C#语言有两个很重要的方面:第一它是为了Microsoft的.NET Framework的结合而设计的,其次它是一种为问题而设计解决问题的方法的语言,它有很多 ...
- 学习ExtjsFor.NET(第二个案例-Array的Every方法)
Ext.Array.every(Array array,Function fn,Object scope)是一个遍历的方法. array是数组,fn是方法,scope是作用域.every返回true和 ...