浅谈最大子序和

题目大意:输入一个长度为 n 的整数序列,从中找出一段不超过 m 的连续子序列,使得整个序列的和最大。

输入: 6 4 1 -3 5 1 -2 3

输出:7

1<=n,m<=300000答案小于long long int

------------------------------------------------------

从题目,要序列中某一段的和,那么前缀和少不了的。所以先处理前缀和。第一步想暴力算法:无非就是一直循环:

for(int i = 1; i <= n; i++)

        for(int j = i - m; j <= i; j++)

                Max = max(Max, sum[i] - sum[j - 1]);

时间复杂度O(nm)。接下来我们想想怎么优化。我们每次循环两遍,都是在求一个值。让f[i]表示循环到i最后取的最大值。根据上述循环可知:

f[i] = max{sum[i] - sum[j - 1]} (i - m <= j  <= i)

对于每一次求f[i],sum[i]是确定的。在这个方程中,被减数确定了, 取最大时,被减数取最小。

这样,问题就转化为了在O(1) ~ O(log(n))时间求某一段区间的最值

下一步,我们就有很多方式解决这个问题了:

1.经典的RMQ问题,直接上ST表

2.线段树和树状数组也可以

3.由于每次求的区间的特殊性(每次求的最值区间相较于上一个往右了一格)

所以可以用单调队列(滑动窗口)

最后上代码:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 300006;
int n, m, Max = -0x3f3f3f3f;
int q[maxn], f = 1, r = 1;
int ar[maxn], qzh[maxn];
int main(){
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i){cin >> ar[i];qzh[i] = qzh[i - 1] + ar[i];}
    for(int i = 1; i <= n; ++i){
        while(f != r && i - q[f] > m){
            f++;
        }
        while(f != r && qzh[q[r-1]] > qzh[i]){
            r--;
        }
        q[r++] = i;
        Max = max(Max, qzh[i] - qzh[q[f]]);
        Max = max(Max, ar[i]);
    }
    cout << Max;
    return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ABAQUS用户子程序是用于对ABAQUS软件进行定制化开发的工具,可以实现用户自定义的功能和算法。用户子程序pdf则是对ABAQUS用户子程序进行详细讲解的文档,可以帮助用户了解和使用用户子程序。 首先,用户子程序是ABAQUS软件的一个重要扩展功能,通过用户子程序,可以使用Fortran或C++等编程语言编写自己的算法和模型,并将其集成到ABAQUS中。用户子程序的开发可以满足用户特定的需求,扩展ABAQUS的功能,实现更复杂的模拟和分析。 用户子程序pdf是ABAQUS官方提供的详细文档,其主要内容包括用户子程序编写的基本概念、开发的流程、编程语言的要求以及具体使用的方法和技巧等。它通常会提供一些示例代码,用于演示如何使用用户子程序实现某些功能。用户可以根据文档的指导,学习和理解用户子程序的使用方法,并将其应用于自己的工程实际中。 用户子程序pdf的作用是帮助用户深入理解和掌握ABAQUS用户子程序的使用方法,可以节省用户的学习和开发成本。通过阅读文档,用户可以了解到用户子程序的原理和特点,学会如何编写、编译和调用用户子程序,并能够在实际使用中解决遇到的问题。用户子程序pdf还提供了一些技巧和注意事项,帮助用户充分发挥用户子程序的功能和性能。 总之,ABAQUS用户子程序pdf是一个重要的学习和参考资料,对于想要使用并扩展ABAQUS功能的用户来说,它是必不可少的。通过学习用户子程序pdf,用户可以掌握用户子程序的开发和使用技巧,为工程实践提供更强大和定制化的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值