acm初学,有点小问题希望大神指点指点

题意是给一个长度为n的数组,求长度不超过m的子数组元素之和的最大值。
结果老是不对,希望大神们能指点指点,感激不尽!!!

我的想法是开一个队列,每次读入的时候sum就加上读入这个的值,如果这个sum小于0了就将读入的队列全部出队,每次用sum和ans比较,如果sum>ans,就更新ans的值,最后结果就是答案了,可是数据一大,结果就不对了。

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n, m;
int  value[100010] = {0};
int MIN[100010] = { 0 };
int qianzhui[100010] = { 0 };
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    queue<long long>s;
    long long sum = 0, ans = 0;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> value[i];
    if (*max_element(value + 1, value + 1 + n) <= 0)
    {
        cout << *max_element(value + 1, value + 1 + n);
        return 0;
    }
    for (int i = 1; i <= n; i++)
    {
        if (s.size() < m)
        {

            s.push(value[i]);
            sum += value[i];
            if (sum < 0)
            {
                while (!s.empty())
                    s.pop();
                sum = 0;
                continue;
            }
            if (sum > ans)
                ans = sum;
        }
        else
        {
            sum -= s.front();
            s.pop();
            s.push(value[i]);
            sum += value[i];
            if (sum < 0)
            {
                while (!s.empty())
                    s.pop();

                sum = 0;
                continue;
            }
            if (sum > ans)
                ans = sum;
        }
    }
    for (; !s.empty();)
    {
        sum -= s.front();
        s.pop();
        if (sum > ans)
            ans = sum;
    }
    cout << ans;
}

这个虽然看着复杂一点,但是思路比较清晰,后面不懂的朋友也可以看看

#include<queue>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long  ll;
struct total
{
    ll x;//x是其值
    int y;//y为其位置
}p[100010];
int n, m;
ll a;
ll sum[100010] = { 0 };
ll max(ll x, ll y);
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> a;
        sum[i] = sum[i - 1] + a;
        p[i].x = sum[i];
        p[i].y = i;
    }
    deque <total> b;
    b.push_back({ 0,0 });
    ll ans = p[1].x;
    for (int i = 1; i <= n; i++)
    {
        while (!b.empty() && p[i].y - b.front().y > m)
                    {
            b.pop_front();
        }
        if (!b.empty() && p[i].x > b.back().x)
        {
            b.push_back(p[i]);
        }
        else {
            while (!b.empty() && p[i].x < b.back().x)
                b.pop_back();
            b.push_back(p[i]);
        }
        if (b.size() != 1)
            ans = max(ans, (b.back().x) - (b.front().x));
        else ans = max(ans, b.back().x);
    }
    cout << ans;
    return 0; 

}

ll max(ll x, ll y)
{
    if (x > y)
        return x;
    else return y;
}

我用java写了一个demo

public static void main(String[] args) {
        Integer[] list = new Integer[]{1,3,5,23,12,1,54,23,5,32,52,52, 1, 1, 1};

        getSubListMaxSum(list, 4);
    }

    private static void getSubListMaxSum(Integer[] list, int m) {
        // m 长度的子数组
        Integer[] subList = new Integer[m];
        // 子数组元素之和最大值
        Integer subListSumMax = 0;

        // 填充子数组
        for (int subListIndex = 0; subListIndex < subList.length; subListIndex++) {
            subListSumMax += list[subListIndex];
            subList[subListIndex] = list[subListIndex];
        }
        System.out.println("初始数组:" + Arrays.toString(subList) + ", 最大值:" + subListSumMax);

        // 新的子数组的最大值
        Integer newSubListSum;

        // 遍历 list[m] 下标开始的数据,比较新旧子数组的值
        for (int listIndex = m; listIndex < list.length; listIndex++) {
            // 将子数组中的第一个元素取出,然后从list中读取一个新值
            // 用上一轮记录的 子数组元素之和最大值 - 子数组第一个值 + list中新值 = 新的子数组的最大值
            newSubListSum = subListSumMax - subList[0] + list[m];
            if (subListSumMax < newSubListSum) {
                subListSumMax = newSubListSum;
            }

            // 用来截取新的子数组
            int listSubIndex = listIndex - m + 1;
            // 更新subList中的数据
            for (int subListIndex = 0; subListIndex < m; subListIndex++) {
                subList[subListIndex] = list[listSubIndex++];
            }
            System.out.println("中间数组:" + Arrays.toString(subList) + ", 最大值:" + subListSumMax);
        }

        System.out.println("结束数组:" + Arrays.toString(subList) + ", 最大值:" + subListSumMax);
    }

你的sum,队列s都是long long型的,但是他们有时候加进去的数是value[i],而value[i]是int型,会不会是这个类型转换出问题了?你把value[i]改成long long试试

图片说明
#include
using namespace std;

int main()
{
long m,n,i,j,k,startid,endid;
long long sum = 0, ans = 0;

 int * value;
 cin >> n >> m;
 value = new int[n];                    // 根据输入构建原数组
 for (int i = 0; i < n; i++)
     cin >> value[i];

ans = value[0];                         // 子数组和初值
for(i=0;i<n;i++)                        // 原数组元素遍历
{   
    for(j=i;j<i+m&&j<n;j++)             // 构成元素个数不大于m的子数组
    {
        sum = 0;
        for(k=i;k<j;k++)                // j-i个元素子数组求和
            sum += value[k];
        if(sum>ans)                     // 取子数组和的最大值并记录该子数组的讫止位
        {
            startid = i;
            endid = j - 1;
            ans = sum;
        }
    }
}

cout << "子数组最大和="<<ans<<endl;
cout<<"最大和子数组讫始位置:"<<startid<<"   结束位置:"<<endid<<endl;
for(i=startid;i<endid;i++) cout<<value[i]<<",";

delete []value;
cin>>i; // 只是暂停

你原来的程序有点小问题,n个元素的数组,下标是从0至n-1,关于子数组最大和的问题,网上有很多方法,我这只是其中一种,比较好理解,但不是最优的。