hdu4604 不错的子序列问题
题意:
给你一个栈,里面有n个数,和一个双头队列(空的),每次从栈里拿出一个数据,有三种选择,可以选择丢弃这个数字,也可以放到队头或者队尾,最后问你这个队列你面的最长连续非下降序列的长度...
思路:
我感觉就是在1025的基础上加强了几个等级,那个题目就是二分贪心求公共子序列,这个题目的细节是用到了1025的思路的,首先我们枚举每一个数,把他当做进队列的第一个数字,那么此时的答案就是 该起点开始的最长费递减子序列 + 该起点开始的最长非递增子序列 - 他们相同的部分.他们相同的部分是的数字肯定是 当前这个数字,那么我们只要找到他俩序列中含有的当前这个数的个数中较小的哪一个减去就行了(相同部分一定是小的是大的子集).值得注意的是我们要倒着枚举数据,减少时间复杂度..
如果没看懂的话我就帮忙回一下1025,正好自己也总结下,dp是自己的弱点,有必要总结..1025 说的是给你n个数(n很大) 求上升子序列...那个题目的思想是 二分 + 贪心(个人感觉 ,有的人认为是 二分 + dp, 随意,dp和贪心相同又不同)开一个数组now[i],记录的是第i个位置最小可以是now[i],对于每一个数num[i]每次我们二分找到num[i],在now[i]中的位置,也就是i,如果这个i>当前长度,那么就更新当前长度,其实这个[i]就是以当前这个数为序列终点的序列的长度,4046上面的那个题目用到的就是在now[i]中再次二分找到now[i]的起始位置,更新的时候我们找的是终止位置,根据这个差我们就找到了重复的num[i]的个数,值得注意一点的就是当前的这个now数组中的数并不是什么子序列的数字,只是单纯的记录某个位置的最小,没有别的意义,光靠这个数组无法输出真正的子序列,但是对于当前时刻当前的num[i],now[i]中连续的num[i]的个数是num[i]为终点的子序列的最后几位数,还有没被别的更新,所以根据now[]中连续的num[i]我们算出的连续num[i].的个数是正确的...
#include<stdio.h>
#include<string.h> #define N 100000 + 500
int upp[N] ,loww[N] ,now[N];
int num[N];
int same[N]; int minn(int x ,int y)
{
return x < y ? x : y;
} int main ()
{
int t ,n ,i;
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&n);
for(i = 1 ;i <= n ;i ++)
scanf("%d" ,&num[i]);
int low ,up ,mid ,len;
now[1] = num[n] ,len = 1;
same[n] = 1;
for(i = n - 1 ;i >= 1 ;i --)
{
low = 1 ,up = len;
int mk = 0;
while(low <= up)
{
mid = (low + up) >> 1;
if(num[i] <= now[mid])
{
low = mid + 1;
mk = mid;
}
else up = mid - 1;
}
mk ++;
if(mk > len) len ++;
now[mk] = num[i];
loww[i] = mk; low = 1 ,up = len;
mk = 0;
while(low <= up)
{
mid = (low + up) >> 1;
if(num[i] < now[mid])
{
low = mid + 1;
mk = mid;
}
else up = mid - 1;
}
same[i] = loww[i] - mk;
} now[1] = num[n];
len = 1;
for(i = n - 1 ;i >= 1 ;i --)
{
low = 1 ,up = len;
int mk = 0;
while(low <= up)
{
mid = (low + up) >> 1;
if(num[i] >= now[mid])
{
low = mid + 1;
mk = mid;
}
else up = mid - 1;
}
mk++;
if(mk > len) len ++;
now[mk] = num[i];
upp[i] = mk;
low = 1 ,up = len;
mk = 0;
while(low <= up)
{
mid = (low + up) >> 1;
if(num[i] > now[mid])
{
low = mid + 1;
mk = mid;
}
else up = mid - 1;
}
same[i] = minn(same[i] ,upp[i] - mk);
} int ans = 0;
for(i = 1 ;i <= n ;i ++)
if(ans < loww[i] + upp[i] - same[i])
ans = loww[i] + upp[i] - same[i];
printf("%d\n" ,ans);
}
return 0;
}
hdu4604 不错的子序列问题的更多相关文章
- HDU1160:FatMouse's Speed(最长上升子序列,不错的题)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1160 学的东西还是不深入啊,明明会最长上升子序列,可是还是没有A出这题,反而做的一点思路没有,题意就不多说 ...
- hdu4604 Deque(最长上升子序列变形)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4604 题意:一个含有n个数栈,每次取出一个数,可以把这个数放在deque(双向队列)首部,放在尾部,或 ...
- {POJ}{3903}{Stock Exchange}{nlogn 最长上升子序列}
题意:求最长上升子序列,n=100000 思路:O(N^2)铁定超时啊....利用贪心的思想去找答案.利用栈,每次输入数据检查栈,二分查找替换掉最小比他大的数据,这样得到的栈就是更优的.这个题目确实不 ...
- HDU 1003 Max Sum && HDU 1231 最大连续子序列 (DP)
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- 2124: 等差子序列 - BZOJ
Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一个整数T,表示组数.下接 ...
- Lintcode--010(最长上升子序列)
给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度.LIS(longestIncreasingSubsequence) 说明: 最长上升子序列的定义: 最长上升子序列问题是在一个无序的给 ...
- 从0打卡leetcode之day 3 -- 最大子序列和
前言 就有要把leetcode的题刷完,每天一道题,每天进步一点点 从零打卡leetcode之day 3 题目描述: 给定一个int类型的数组,求最大子序列的和. 也就是说,从这个数组中截取一个子数组 ...
- 动态规划--最长上升子序列(Longest increasing subsequence)
前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...
- 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列
0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...
随机推荐
- nignx的location正则匹配
原文链接:http://nginx.org/en/docs/http/ngx_http_core_module.html Syntax: location [ = | ~ | ~* | ^~ ] ur ...
- 设计模式系列之原型模式(Prototype Pattern)——对象的克隆
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- ts装饰器的用法,基于express创建Controller等装饰器
TS TypeScript 是一种由微软开发的自由和开源的编程语言.它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类 型和基于类的面向对象编程. TypeScript 扩 ...
- Java数组:多维数组(二维),Arrays类,冒泡排序
Arrays类数组工具类:java.util.ArraysArrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用 具有 ...
- slickgrid ( nsunleo-slickgrid ) 2 修正区域选择不能跨冻结列的问题
slickgrid( nsunleo-slickgrid ) 2 修正区域选择不能跨冻结列的问题 周六的时候,留了个小小的尾巴,区域选择的问题进做到了定位: 问题原因,在slickgrid启动冻结之 ...
- 你想知道的 std::vector::push_back 和 std::vector::emplace_back
引言 C++ 11 后,标准库容器 std::vector 包含了成员函数 emplace 和 emplace_back.emplace 在容器指定位置插入元素,emplace_back 在容器末尾添 ...
- for-in 语句
for-in 语句循环专门用于遍历范围,列表,元素和字典等可迭代对象. 循环中的变量的值受for-in循环控制,该变量将会在每次循环开始时自动被赋值,因此程序不应该在循环中对该变量进行赋值 for-i ...
- c++ 反汇编 构造函数和析构函数
构造函数和析构函数出现的时机 局部对象 109: // 局部对象定义调用构造函数 110: 111: CNumber Number; 00C8A37D 8D 4D EC lea ecx,[Number ...
- 在 .NET Core 5 中集成 Create React app
翻译自 Camilo Reyes 2021年2月22日的文章 <Integrate Create React app with .NET Core 5> [1] Camilo Reyes ...
- 微信小程序实现搜索关键词高亮
目录 1,前言 2,思路 3,代码逻辑 1,前言 项目中碰到一个需求,搜索数据并且关键词要高亮显示,接到需求,马上开干.先上效果图.源码已经做成了小程序代码片段,放入了GitHub了,文章底部有源码链 ...