首页 > 编程语言 >【算法】尺取法

【算法】尺取法

时间:2024-12-19 13:28:37浏览次数:4  
标签:二分 松果 2522% blog 算法 查找 取法 蹦蹦

Hello!大家好,我是@学霸小羊,今天来讲讲尺取法。

话说回来,枚举算法应该对大家来说很简单(不会还有新手不会吧)。

枚举又有许多高级的分支,都用于节省时间复杂度。

例如:二分查找和二分答案——

二分查找与二分答案_二分查找和二分答案的区别-CSDN博客文章浏览阅读102次。以在一个升序数组中查找一个数为例。它每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需到右侧查找;如果中间元素大于所查找的值同理,只需到左侧查找。二分答案:答案有一个区间,在这个区间中二分,直到找到最优答案。二分查找:在一个已知的有序数据集上进行二分地查找。二分算法可以分为二分查找和二分答案。首先明确二分查找与二分答案有何区别?_二分查找和二分答案的区别https://blog.csdn.net/yangyanbin_sam/article/details/138767413?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522f22f19e4b28d48cc5a37b5931aa9cfdb%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=f22f19e4b28d48cc5a37b5931aa9cfdb&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-138767413-null-null.nonecase&utm_term=%E4%BA%8C%E5%88%86&spm=1018.2226.3001.4450【关于二分】-CSDN博客文章浏览阅读894次,点赞30次,收藏14次。二分的介绍https://blog.csdn.net/yangyanbin_sam/article/details/138797821?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522f22f19e4b28d48cc5a37b5931aa9cfdb%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=f22f19e4b28d48cc5a37b5931aa9cfdb&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-138797821-null-null.nonecase&utm_term=%E4%BA%8C%E5%88%86&spm=1018.2226.3001.4450但进行二分是有前提的:数据要有序。

那么如果要在一些数中取一段,但又必须保持原来的顺序……

请看题目(又不是VCR)!

题目描述

给定一个长度为 N ( 10 < N < 100000 )的正整数序列。每个正整数都小于等于 10000 ,给定一个正整数 S ( S < 100000000 )。编写一个程序找到一个最小长度的子序列,要求这个子序列的和大于等于 S 。如果解不存在,则输出 0 。

输入格式

第一行两个整数 N 和 S;

第二行包括 N 个正整数表示数列 A ,两两之间用空格分隔。

输出格式

一个整数。

样例

输入数据 1

5 11
1 2 3 4 5

输出数据 1

3

这题就要用到尺取法了。

在做题前,先了解一下理论知识。

尺取法是一种线性算法,也是一种高效的枚举区间的方法。

记 (l,r) 两个端点为一个序列内以 l 为起点的最短合法区间,如果 r 随 l 的增大而增大的话,我们就可以使用尺取法。

具体的做法是:

  1. 初始化左右端点

  2. 不断扩大右端点,直到满足条件

  3. 如果第二步中无法满足条件,则终止,否则更新结果

  4. 将左端点扩大1,然后回到第二步

因为 r 随 l 增大而增大,所以 r 只有 n 次变化的机会,所以时间复杂度为 O(n) 。

经典例子

给定一个长度为 n 的数列 a_1, a_2, ..., a_na1​,a2​,...,an​ 及整数 S ,求不小于 S 的连续子序列的和的最小值,假设解肯定存在。

input

n=10,S=15

a= {5,1,3,5,10,7,4,9,2,8}

尺取法示意图

首先,取得满足条件的最小序列,然后依次将响右移动,若 i 向左移动的过程中序列仍然满足条件,则不移动,否则将也向右移动。

在移动的过程中记录 j-i 的最小值。

好啦,刚才已经讲了基本思路,打一打刚才题目的代码吧!

参考代码 

#include<bits/stdc++.h>
using namespace std;
long long n,a[100005],s[100005],mi=INT_MAX,sum,i=1,j;
long long ss;
int main()
{
    cin>>n>>ss;
    for(int x=1;x<=n;x++)
    {
    	cin>>a[x];
        sum+=a[x];
        s[x]=s[x-1]+a[x];
        if(sum>=ss) sum=INT_MIN,j=x;
    }
    for(;j<=n;)
    {
        if(s[j]-s[i-1]>=ss) mi=min(j-i+1,mi),i++;
        else j++;
        if(i==j) j++;
    }
    if(mi==INT_MAX)mi=0;
    cout<<mi;
    return 0;
}

接下来,讲一个变式。

题目描述

大森林有熊兄弟的好朋友松鼠蹦蹦,一天蹦蹦来到一条很长的小 路,发现沿路地上都有松果,高兴极了,决定尽可能多吃松果。

蹦蹦观察到,每个松果的重量并不一定相同,可蹦蹦的肚子容量 有限,总共最多只能吃重量 C 的松果。
蹦蹦吃东西有个特点,一旦开吃就会不停的吃,不会漏过路上碰 到松果,直到遇到一个吃不下或吃完停止。也就是说松鼠蹦蹦只会吃 连续一段的松果。

已知路上共有 N 个松果,顺序的重量是 w_1, w_2,..., w_nw1​,w2​,...,wn​ 。蹦蹦最多可能吃多少颗松果?

输入格式

第一行,二个正整数,空格分开,表示 N 和 C,N 范围在[1..50000], C 范围在[1..1000000]。

第二行,N 个正整数,空格分开,表示从 w_1、w_2,..., w_nw1​、w2​,...,wn​ ,即松果的重量。每个松果重 量范围在[1..1000]。

数据范围

一个正整数,蹦蹦可以吃到的最多松果数量。

输出格式

样例

输入数据 1

5 5
3 1 2 1 1

输出数据 1

4

输入数据 2

9 5
1 5 4 3 2 1 1 4 1

输出数据 2

3

样例解释

样例 1 :吃:(1,2,1,1)这段的松果。

样例 2 :吃:(2,1,1)这段的松果。

原来我们是符合条件就更新minn或maxx,这题就有点不一样了。

大家先想想吧!下一个博客揭晓答案!

标签:二分,松果,2522%,blog,算法,查找,取法,蹦蹦
From: https://blog.csdn.net/yangyanbin_sam/article/details/144583445

相关文章

  • Java笔记(数据结构与算法[树、栈、列表、队列、数组])
    Java笔记(数据结构与算法[树、栈、列表、队列、数组])链表栈,队列,数组树易错点:二叉树的插入,数据往二叉树里面插入的时候,每一个数据都要和每一个节点相比较,不可能插入到某两个节点中间,最后一定是挂(添加)到二叉树的最后一排的某个节点上度:每......
  • 数据结构与算法学习笔记----Dijkstra
    数据结构与算法学习笔记----Dijkstra@@author:明月清了个风@@firstpublishtime:2024.12.17ps⭐️两个版本的都是模版题,算法讲解直接放在每一题里了,思路中还有对于稀疏图和稠密图的介绍,注意优化版的dijkstra中有几点注意点是和朴素版不一样的。Acwing849.Dijkstr......
  • 数据结构与算法学习笔记----SPFA算法
    数据结构与算法学习笔记----SPFA算法@@author:明月清了个风@@firstpublishtime:2024.12.19SPFA算法这同样是一种单源最短路径算法,是队列优化的Bellman-ford算法,因此他能处理的情况和Bellman-ford算法一样,但是在一般情况下,时间复杂度更低,为......
  • C#选择排序算法实操
    选择排序原理介绍选择排序(SelectionSort)是一种简单的排序算法,其实现原理如下:遍历待排序数组,从第一个元素开始。假设当前遍历的元素为最小值,将其索引保存为最小值索引(minIndex)。在剩余的未排序部分中,找到比当前最小值还要小的元素,并更新最小值索引。在遍历结束后,将找......
  • 【创新、复现】基于蜣螂优化算法的无线传感器网络覆盖优化研究(Matlab代码实现)
    ......
  • 算法总结
    复杂度1GhzCPU的1s大约运算1e8次,n(1e8),n²(10000),n³(500),2^n(27)n!的弱上界n^n开数组的时候,a[1e9],约为2^32,超过1G内存,堆没有那么大,会堆溢出(1e8≈2^27)动态创建数组静态分配(从进程空间/虚拟地址来看是连续的,实际物理内存不一定连续)函数中使用数组:栈,最大......
  • 算法总结2
    多维数组和矩阵顺时针打印1 2 3 45 6 7 8910111213141516打印结果:12348121615141395671110voidprint(intmatrix[][],intlen1,intlen2){intlux=0;//leftup.xintluy=0;//leftup.yintrdx=len1-1;//rightdow......
  • 《C++与 Armadillo:线性代数助力人工智能算法简化之路》
    在人工智能领域,线性代数运算可谓是构建各类模型与算法的基石。从神经网络中的矩阵乘法、向量运算,到数据处理中的特征分解、奇异值分解等,无一不依赖高效且精准的线性代数计算。而C++作为一种强大且高效的编程语言,在人工智能开发中有着独特的地位。Armadillo库的出现,则为在......
  • 偷懒算法第二天
    1注意:最后一排如果是奇数就拿中间数;如果是偶数就拿中间比较大的哪一个左右距离为1.2注意:思路为先构造数组,0-9各2021个,再遍历数字,取出数字1-9,当数字都用完后,拿出i-这个数字,去除t最后一个数字,因为最后一个数字已经不够了,取不到了。......
  • 【阿里matlab算法】matlab实现超启发驱动贝叶斯散斑去噪MDBSD研究——散斑去噪
    MATLAB实现超启发驱动贝叶斯散斑去噪MDBSD研究1、项目下载:本项目完整论文和全套实现源码见下面资源,有需要的朋友可以点击进行下载说明文档(点击下载)本算法文档matlab实现超启发驱动贝叶斯散斑去噪MDBSD-贝叶斯去噪-MDBSD-图像处理-散斑噪声更多阿里matlab精品项目可点击......