尺取法的应用

  尺取法其实是一种很简单的算法,思想原来也用过,但一直不知道。。这两天恰好做了两道有关尺取法的题,就来总结一下。

  首先,什么是尺取法?尺取法通常是指对数组保存一对下标(起点、重点),然后根据实际情况交替推进两个端点直到得出答案的方法,因为这种方法像尺取虫的爬行方式所以得名。其实就是求在一个线性的数组上求关于区间的问题。由于只对区间的两个端点进行改变,所以中间部分就不需要进行维护更新了,只要维护两端即可。可以大大降低复杂度。

  例题一:poj3061 给定长度为n的整数数列以及整数S,求出总和不小于S的连续子序列的长度的最小值,如果解不存在,输出0。

  解法一:(1)s=t=sum=0初始化

      (2)只要sum<S,就不断将sum增加a(t),并将t增加1

      (3)如果(2)中无法满足sum>=S则终止,否则将ans更新为min(ans,t-s)。

      (4)将sum将sum减去a(s),s增加1后回到(2)

      这其实就是一个典型的尺取法,我们当得到sum>=S时再减去a(s)它又会小于S就相当于重新确定了起点,同样的,也就同时确定了终点,并且因为新区间和原来的区间有很大一部分重合,所以直接对sum进行加减就可以了,无需重新计算。

  例题二:给出一串珠子,有2n个,其中有黑色和白色珠子各n个,黑色逆时针编号,白色顺时针编号,白色黑色随机排列,要找一段长度为n的区间,要求区间内珠子的编号为1-n(不一定从小到大或从大到小出现,只要1-n都出现即可)。(感谢畅神出题!)数据范围1000万。

  解法二:由于数据范围很大,所以必须用O(n)的方法解。我们先把珠子编好号,然后找一个作为起点,向后找n个珠子,记录下每种编号的珠子各有几个和一共出现了几个编号的珠子。然后,我们将头上的珠子取出,加上第n+1个珠子,重复该过程,直到出现了n个编号的珠子我们就找到了一个合法区间。这也是尺取法的一种,中间n-2个珠子我们是不需要管的,只要取出和加上头和尾的珠子就行了。这样只要枚举n个起点就可以轻松找出这个区间。

  总结:总的来说尺取法的思想很好理解,代码难度不算高,在noip中考很合适,有些题可以方便的解决,个人感觉应该掌握。

时间: 2024-10-20 17:15:07

尺取法的应用的相关文章

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

hihocoder-1483区间价值 (二分+尺取法)

题目链接: 区间价值 给定n个数A1...An,小Ho想了解AL..AR中有多少对元素值相同.小Ho把这个数目定义为区间[L,R]的价值,用v[L,R]表示. 例如1 1 1 2 2这五个数所组成的区间的价值为4. 现在小Ho想知道在所有的的v[L,R](1 <= L <= R <= n)中,第k小的值是多少. Input 第一行一个数T(T<=10),表示数据组数. 对于每一组数据: 第一行两个数n,k(1<=n<=200,000,1<=k<=n*(n+1

【转】毛虫算法&mdash;&mdash;尺取法

转自http://www.myexception.cn/program/1839999.html 妹子满分~~~~ 毛毛虫算法--尺取法 有这么一类问题,需要在给的一组数据中找到不大于某一个上限的"最优连续子序列" 于是就有了这样一种方法,找这个子序列的过程很像毛毛虫爬行方式,我管它叫毛毛虫算法,比较流行的叫法是"尺取法". 喏,就像图里的妹纸一样~ 还是举个栗子: Poj3061 给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度 输入 n = 1

51nod1127(尺取法)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1127 题意:中文题诶- 思路:尺取法 维护一个队列,若当前队首的元素在后面出现了,那么我们就将其删除,若当前队列里含有26个字母,我们就记录其size. 取所有size里面的最小值就是我们要的答案... 代码: 1 #include <iostream> 2 #include <stdio.h> 3 #include <string>

BestCoder Round #86 二,三题题解(尺取法)

第一题太水,跳过了. NanoApe Loves Sequence题目描述:退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nnn 的数列,他又根据心情随便删了一个数,这样他得到了一个新的数列,然后他计算出了所有相邻两数的差的绝对值的最大值. 他当然知道这个最大值会随着他删了的数改变而改变,所以他想知道假如全部数被删除的概率是相等的话,差的绝对值的最大值的期望是多少. 输入描述 第一行为一个正整数 T,表示数据组数. 每组数

POJ 3320 尺取法,Hash,map标记

1.POJ 3320 2.链接:http://poj.org/problem?id=3320 3.总结:尺取法,Hash,map标记 看书复习,p页书,一页有一个知识点,连续看求最少多少页看完所有知识点 必须说,STL够屌.. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio>

HDU 5672 String 尺取法追赶法

String Problem Description There is a string S.S only contain lower case English character.(10≤length(S)≤1,000,000)How many substrings there are that contain at least k(1≤k≤26) distinct characters? Input There are multiple test cases. The first line

hdu-5672 String(尺取法)

题目链接: String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 有一个 10\leq10≤长度\leq 1,000,000≤1,000,000 的字符串,仅由小写字母构成.求有多少个子串,包含有至少k(1 \leq k \leq 26)k(1≤k≤26)个不同的字母? 输入描述 输入包含多组数据. 第一行有一个整数T (1\leq T\leq 10)T(1≤T≤1

poj 3320 Jessica&#39;s Reading Problem (尺取法)

Jessica's Reading Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8787   Accepted: 2824 Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent littl