美丽的亚得里亚海沿岸有N家酒店。每个酒店都有 它的价值是欧元。
Sroljo在乐透区赢得了M欧元。现在他想买一个序列 连续酒店,这些值的总和 连续酒店尽可能好 - 但不超过M.
我被要求计算最大可能值。 我的代码是:
big=-1;
for(i=0;i<n;i++)
{
sum=0;
for(j=i;j<n;j++)
{
sum+=A[j];
if(sum<m)
{B[i]=sum;continue;}
if(sum>m)
{B[i]=(sum-A[j]); break;}
if(sum==m)
{printf("%d\n",m); exit(1);}
}
if(B[i]>big)
big=B[i];
}
printf("%lld",big);
,这是O(n ^ 2),对我来说太慢了。怎么能在O(n)中完成?
答案 0 :(得分:3)
好的,这就是如何,对未来的googlers来说太明显了。
将酒店按照从左到右的顺序排列在列表中。
使用从索引i开始到j(i <= j)结束的“移动窗口”,同时保持该窗口中酒店价格的当前总和(s
)。任务是找到s
最大的s <= M
。
如果窗口中包含的价格总和(j
)不超过Sroljo的预算,您可以将窗口窗口向右扩展(在s
侧)。
如果总和超过了Sroljo的预算,您必须从左侧(i
侧)缩小窗口。
您可以在每个步骤维护到目前为止找到的最大法定金额,并相应地进行更新。
将窗口移动到从此算法获得的所有位置后,到目前为止找到的最大总和是您正在寻找的。 p>