带限制的最大数组和

时间:2013-10-28 06:59:42

标签: c++ arrays dynamic-programming

无法找到这个问题。我们得到一个数组,我们必须找到连续元素的最大总和但是给出了最大总和限制。对于数组7 3 5 6,最大允许总和是9,所以回答应该是8。我在互联网上找到的唯一的东西是最大可能的总和,但我想找到有限的总和

#include<iostream>
#include<algorithm>
using namespace std; 

int main() 
{
    int n,m,a[100],dp[100];
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    int sum=0;
    for(int i=0;i<n&&sum<=m;i++) 
    {
        int j=0;
        sum=sum+a[i];
        if(sum>m)
        {
            dp[j]=sum-a[i];
        }
        else dp[j]=sum;
        j++;
        sum=0;
    }
    sort(dp,dp+n);
    cout<<dp[n-2];
    return 0;
}

3 个答案:

答案 0 :(得分:1)

如果数组中的数字都是正数,则这是一个O(n)算法:使用2个指针,一个指向起始位置,另一个指向结束位置。将当前的指针向前移动,只要当前总和大于限制,移动第一个指针并减去总和。

简单代码:

int sum=0,ans=0,p1=0,p2=0;
while (p2<n) {
    sum+=num[p2];
    p2++;
    while (sum>limit && p1<p2) {
        sum-=num[p1];
        p1++;
    }
    ans=max(ans,sum);
}
while (p1<n) {
    sum-=num[p1];
    p1++;
    if (sum<=limit) ans=max(ans,sum);
}
return ans;

如果数组包含负数,目前我只能想到O(n ^ 2)算法。

答案 1 :(得分:0)

通过以下逻辑动态编程解决了经典的最大和问题:

  • S[i]为结束于数组索引i的最大总和。
  • array成为包含正值或负值的长度为n的数组
  • 我们知道S[0] = array[0]因为在索引0之前数组中没有其他值。
  • S[i] = max(S[i-1] + array[i], array[i])也就是说,索引i可达的最大值是array [i]加到前一个最大值,或者只是array [i]。如果先前的最大值为负或0,那么我们总是想采用array [i],而这个逻辑就是这样做

动态编程解决方案具有O(n)复杂度。

您的问题略有不同。你有一个S [i]的上限。此上限会显着改变问题的复杂性,因为现在我们可能希望累积负数以达到最大限制。即,输入:

  

-1 -2 6,LIMIT = 3

我们希望发现我们确实可以达到我们的极限。

我们可以通过考虑从array[i]开始的所有可能的连续序列来解决O(n 2 )时间内的这个问题,这是每个索引的O(n)时间。这不是一个非常动态的编程,但我认为它是我们能够获得的最有效的。

答案 2 :(得分:0)

我想你可以在这里找到你问题的完整答案: Algorithm for Filling bag maximally (this is not the knapsack 0/1) 这个问题是我创建的,随时可以询问详情:)