要么借鉴往年,要么借鉴文献。
一、摘要
1.1 摘要结构
- 问题引入
- 各小问的解决方案叙述
- 总结部分
- 关键词
这个东西我弄得还不是很明白,所以先放一篇博客:https://www.cnblogs.com/I-Love-You-520/p/13454305.html
单调队列说的就是博客中提到的场景,可以说解决的是固定长度,多次查询一段的最值(其实就是slice window的意思),这种如果是朴素算法的话,因为查一段序列的最值的时间复杂度是 $O(k)$ (k 是序列长度),然后这段序列需要平移改变,所以外层有一个循环,这样复杂的就是 $O(nk)$ (如果序列长为 n )。采用单调序列的方式,可以让时间复杂度下降到 $O(n)$ 。单调队列的队头即为所求。
此外,关于这篇博客的算法,其实队列中存储的是原数组的下标,而不是原数组元素的值。当然,如果写的更好一些,可以有一个封装,如下所示
typedef long long LL;
struct monotone_queue
{//单调队列
int head,tail,id[N];
LL d[N];
inline void init()
{
// 这种方法处理感觉有点low,只是为了判断队空与否
head = 1,tail = 0;
}
//v就是入队的值,x是数组索引(下标)
inline void push(LL v,int x)
{ //第一个参数为dp[i][x]
while(head <= tail && d[tail] <= v)
tail--;
d[++tail] = v;
id[tail]=x;
}
//x是数组索引
inline void pop(int x)
{//弹出,指的是当范围移动的时候,要把移出范围的元素删掉
while( head <= tail && id[head] - x >= s)
head++;
}
}q;
在这个代码里面,采用了两个数组,d
数组用来储存值(也就是队列功能,这个队列就是最丑陋的非循环队列),而 id
数组用来实现数组元素的移出。每次移动框,都是先插入,然后弹出。
【题目描述】
给定N个数,求这N个数的最长上升子序列的长度。
也就是说,对于给定的序列,保持序列的原有输出不变,从中挑选出一个子集,使其可以满足从小到大的顺序,比如说下面的 2 3
就是符号要求的上升序列,但是 3 5
不行,因为顺序发生了交换。
【样例输入】
7
2 5 3 4 1 7 6
首先,最重要最需要强调的是,排版是一个信息量极大的工程。字体,格式,对齐方式,页眉页脚,都只是排版的冰山一角,可以说,一个人是没有办法完全控制一个印刷文件里面的所有排版细节的,就好像人们可以挑选衣服的颜色,款式,但是人们却对“编织手法,扣子是材质”之类的问题疏于关注,这是因为这些细节没办法全部被考量,人类的大脑接受不了这么多的信息。
由此就衍生出了排版里面我最看重的一个概念,就是“缺省”。正是由于人们没有办法关注到每一个细节,所以对于用户没有办法关注到的细节,软件开发者就必须提供“默认设置”,也就是“缺省”。当然理想的缺省是没有任何问题的,人们可以随意修改自己关心的缺省设置为自己的设置,而对于自己不关心的设置就采用“默认设置”。
但是事实似乎并不是这样的,修改缺省设置并不是简简单单的,我曾经为了在word中将目录调成人能看的样子,查阅各种资料查了一个小时,最后手敲的目录。由此就引出了一个基本的问题:似乎缺省设置侵犯了用户排版的权利。而我评价一款排版编辑工具的好坏,最重要的就是看它在我看重的的设置中修改的难度。