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出这题,反而做的一点思路没有,题意就不多 ...
- PAT甲级1045 Favorite Color Stripe (30 分):[C++题解]最佳彩色带、DP、公共子序列变形
文章目录 题目分析 题目链接 题目分析 来源:acwing 分析:这是一个公共子序列的问题.但是有点变式,序列a和序列b不是完全等价的,序列a的每个元素可以对应多个相同元素,而且有些元素可以不使用.比 ...
- HDU1159(dp最长公共子序列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Problem Description A subsequ ...
- 动态规划:openjudge 2.6-3532 最大上升子序列和 解题心得
传送门 题目描述 一个数的序列bi,当b1 < b2 < - < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, -,aN),我们可以得到一些上升的子序列(a ...
- 最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和...
最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和 文章作者:Yx.Ac 文章来源:勇幸|Thinking (http://www.ahathi ...
- 从0打卡leetcode之day 3 -- 最大子序列和
前言 就有要把leetcode的题刷完,每天一道题,每天进步一点点 从零打卡leetcode之day 3 题目描述: 给定一个int类型的数组,求最大子序列的和. 也就是说,从这个数组中截取一个子数组 ...
- 一分钟搞定最长公共子序列与最长公共子串的问题
感谢大家的理解与指正!觉的写的不错的小伙伴儿,一键三连支持一下,后期会有持续更新!!抱拳了罒ω罒 最长公共子序列和最长公共子串都是动态规划的经典题型,最长公共子序列要求的是不一定连续,最长公共子串 ...
- 动态规划-- 数组最大不连续递增子序列
应该把这个问题看成一个基本问题,感觉用动态规划的算法比较容易想到,也很不错,关于那个改进的O(nlogn)的算法有些不太明白,大部分动态规划都要寻求一个当前状态的最小值或最大值,如果按这样的思想,那不 ...
- 吉首大学2019年程序设计竞赛(重现赛) 干物妹小埋(线段树求最长上升子序列)
链接:https://ac.nowcoder.com/acm/contest/992/B 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...
最新文章
- Kong APIGW — Plugins — 监控告警、日志审计
- android线程栈默认大小,线程的默认最大堆栈大小 - Internet Information Services | Microsoft Docs...
- 确保字符串的每个单词首字母都大写,其余部分小写
- Android(二)——汉化版Eclipse的中英文切换
- 2027. 转换字符串的最少操作次数
- 设置dns_网络速度缓慢怎么办?轻松一键修改DNS设置让网速提升五倍
- 六、Linux企业级YUM软件管理
- 问卷统计前奏【SPSS 072期】
- python写刷课脚本_python opencv 知到 刷课 脚本
- Linux ftpget和ftpput命令
- 一文读懂 HBase 使用场景
- 华为设备,什么是MAC地址漂移
- 中考考试的指令广播_考试时间指令(铃声).doc
- 【VUE】在vue中使用google地图
- Swift语言难度大吗?适不适合零基础学习?
- Hadoop中Namenode单点故障的解决方案
- [英语竞赛] 知识整理
- Python SyntaxError: Non-ASCII character '\xe5' in file
- MATLAB去除数据中的异常值、离群值
- html网页id怎么改成名字,IG 改名字:教你如何更改 Instagram 帐号名称 ID 及个人档案姓名...