尺取--(毛毛虫算法)

尺取算法也叫毛毛虫算法,因为计算过程有点类似毛毛虫一点点的往前挪,在挪动的过程中可以得到一些需要的解。(自动脑补)
通过两个变量来保存所选取区间的左右端点,然后不断的推进区间,寻找所需要的答案(尺取的精髓),其实也是一种暴力枚举方法,不过是有技巧的枚举,所以尺取算法比一般的算法快的多,尤其是数据量比较大的时候,尺取就显得非常有用,所以也是acm经常用到的算法之一。

通过一个例题来理解这个算法

冬天与火锅更配

冬日里的一抹暖阳总是能给人们留下深刻的记忆,人们喜爱冬天的太阳,就跟人们喜爱冬天的火锅一般。
寒冷的冬天总会让人想起火锅,最近小Z特别想去吃火锅,刚好某家转转火锅刚开业有活动,有n盘火锅围成一个圈,第一盘和最后一盘是相连的,每一盘火锅都有一个价值a[i],现在可以吃连续的m盘火锅,小Z想知道他所吃的那连续的m盘火锅的最大价值可以是多少?你能帮帮憨憨的小Z吗。

输入格式

第一行数入两个整数n,m(1<=m<=n<=2000000),分别表示火锅的盘数和可以吃的连续的盘数
第二行输入n的数a[i] (1<=a[i]<=100000),分别表示每一盘火锅的价值

输出格式

输出一个整数,表示连续m盘火锅的最大价值

样例输入

5 3
6 1 2 5 3

样例输出

14

分析:

这个题实际就是求连续m个数和的最大值,想必很多人也是一开始暴力模拟一遍,然后提交是时间超限,这里最坏的时间复杂度是O(n^2),这个题的数据量比较大,所以考虑用尺取。
下面看一下核心代码

#include<stdio.h>
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int a[n];
        int t=0;//表示推进的m
        int tail=0;//表示毛毛虫的尾巴
        long long max1=-1;//所求的最大值
       	long long sum=0;
        for(int i=0;i<n;i++)
            scanf("%d",a+i);
        while(1)//尾巴不爬到最后就一直往前爬
        {
            while(t<m)//毛毛虫向前爬m个位置
            {
                int tt=tail+t;
                if(tt>=n)//头爬到最后得到第一个位置去
                    tt%=n;
                sum+=a[tt];
                t++;
            }
            if(sum>max1)max1=sum;
            sum-=a[tail];//得到一次连续m个数和之后减去尾巴的值
            tail++;//尾巴向前挪一个
            if(tail==n-1)break;//如果尾巴到了最后一个就可以退出了
            t--;//长度减一(尾巴)
        }
        printf("%lld\n",max1);
    }
}

可以看出尺取把原来的时间复杂度O(n^2)变成了O(n),在效率上得到了很多的提高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值