题意:

      给你一个栈,里面有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 不错的子序列问题的更多相关文章

  1. HDU1160:FatMouse's Speed(最长上升子序列,不错的题)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1160 学的东西还是不深入啊,明明会最长上升子序列,可是还是没有A出这题,反而做的一点思路没有,题意就不多说 ...

  2. hdu4604 Deque(最长上升子序列变形)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4604 题意:一个含有n个数栈,每次取出一个数,可以把这个数放在deque(双向队列)首部,放在尾部,或 ...

  3. {POJ}{3903}{Stock Exchange}{nlogn 最长上升子序列}

    题意:求最长上升子序列,n=100000 思路:O(N^2)铁定超时啊....利用贪心的思想去找答案.利用栈,每次输入数据检查栈,二分查找替换掉最小比他大的数据,这样得到的栈就是更优的.这个题目确实不 ...

  4. 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 ...

  5. 2124: 等差子序列 - BZOJ

    Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一个整数T,表示组数.下接 ...

  6. Lintcode--010(最长上升子序列)

    给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度.LIS(longestIncreasingSubsequence) 说明: 最长上升子序列的定义: 最长上升子序列问题是在一个无序的给 ...

  7. 从0打卡leetcode之day 3 -- 最大子序列和

    前言 就有要把leetcode的题刷完,每天一道题,每天进步一点点 从零打卡leetcode之day 3 题目描述: 给定一个int类型的数组,求最大子序列的和. 也就是说,从这个数组中截取一个子数组 ...

  8. 动态规划--最长上升子序列(Longest increasing subsequence)

    前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...

  9. 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列

    0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...

随机推荐

  1. 解决 DatePickerDialog 在 Android7.0 API24 上使用 AlertDialog.THEME_TRADITIONAL、AlertDialog.THEME_HOLO_DARK、AlertDialog.THEME_HOLO_LIGHT等样式时无法显示为 Spinner 样式的问题

    DatePickerDemoForAndroid24 解决 DatePickerDialog 在 Android7.0 API24 上使用AlertDialog.THEME_TRADITIONAL.A ...

  2. salesforce零基础学习(一百零一)如何了解你的代码得运行上下文

    本篇参考:https://developer.salesforce.com/docs/atlas.en-us.228.0.apexcode.meta/apexcode/apex_enum_System ...

  3. solr 远程代码执行(CVE-2019-12409)

    Apache Solr 远程代码执行漏洞(CVE-2019-12409) 简介 Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.是apache的顶级开源项 ...

  4. 测试工程师Docker进阶

    学习整理来源 B站 狂神说Java https://space.bilibili.com/95256449/ 四.docker镜像 1.镜像是什么 镜像是一种轻量级.可执行的独立软件包,用来打包软件运 ...

  5. Java中的名称命名规范:

    Java中的名称命名规范:(不遵守,也不会出现编译的错误) 包名:多单词组成时所有字母都小写:xxxyyyzzz 类名.接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz 变量名.方法名: ...

  6. Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】

    一.题目 D2. Submarine in the Rybinsk Sea (hard edition) 二.分析 相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的. 但 ...

  7. java IO流文件拷贝文件(字符流标准写法)

    public static void copyFile2(String path1, String path2) { Reader reader = null; Writer writer = nul ...

  8. python inspect库

    一.介绍 inspect模块用于收集python对象的信息,可以获取类或函数的参数的信息,源码,解析堆栈,对对象进行类型检查等等. inspect模块主要提供了四种用处: 对是否是模块.框架.函数进行 ...

  9. 如何在 ASP.Net Web Forms 中使用依赖注入

    依赖注入技术就是将一个对象注入到一个需要它的对象中,同时它也是控制反转的一种实现,显而易见,这样可以实现对象之间的解耦并且更方便测试和维护,依赖注入的原则早已经指出了,应用程序的高层模块不依赖于低层模 ...

  10. International Collegiate Programming Contest 2019 Latin American Regional Contests Problem K

    题目链接:https://codeforces.ml/gym/102428/attachments/download/9820/statements-en.pdf 题意:构造一个多项式使得外星人编号的 ...