我在hotels from spoj中超出了时间限制。
这是我的代码:
int main()
{
long long n,m;
scanf("%lld",&n);
scanf("%lld",&m);
long long a[300005],dp[300005];
for(int i=0;i<n;i++) scanf("%lld",&a[i])
for(int i=1;i<n;i++) a[i]+=a[i-1];
for(int i=n-1;i>=0;i--)
{
if(a[i]<m){
dp[0] = a[i];
break;
}
}
for(int i=1;i<n;i++)
{
long long x = a[i-1];
for(int j=i;j<n;j++)
{
a[j]-=x;
}
for(int j=n-1;j>=i;j--)
{
if(a[j]<=m){
dp[i] = a[j];
break;
}
}
}
long long max_=0;
for(int i=0;i<n;i++)
{
max_ = max(max_,dp[i]);
}
printf("%lld\n",max_);
return 0;
}
阐释:
首先,我计算了数组中的所有值&#34; a&#34;然后,将最大值小于等于&#34; m&#34;然后,我开始从前一个减去数组的每个元素的当前值减去dp数组中的存储值。所以,dp数组的最大值会给我答案。
例如: N = 5,M = 12;
2 1 3 4 5
我的阵列&#39; a&#39;: 2 3 6 10 15
然后在第二次传球后: 2 1 4 8 13
然后在第3次传球后: 2 1 3 7 12
这里有代码: Ideone
答案 0 :(得分:0)
这个问题有复杂性O(n)。
#include <iostream>
using namespace std;
int a[300013];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++) scanf("%d",&a[i]);
long long sumNow = 0;
long long maxAns = 0;
int left=0,right=-1;
while(right!= n-1){
right++;
sumNow+=a[right];
while(sumNow>m){
sumNow-=a[left];
left++;
}
maxAns = max(maxAns,sumNow);
}
printf("%lld", maxAns);
return 0;
}