无法找到这个问题。我们得到一个数组,我们必须找到连续元素的最大总和但是给出了最大总和限制。对于数组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;
}
答案 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) 这个问题是我创建的,随时可以询问详情:)