装饰效果
题目描述
小明在美术课上给马上要过生日的妈妈做了张贺卡,为了装饰这张贺卡,小明买了一条彩带,但是彩带上并不是所有颜色小明都喜欢,于是小明决定裁剪这条彩带,以取得最好的装饰效果。
现已知彩带由n种不同的颜色顺次相接而成,而每种颜色的装饰效果用一个整数表示(包括正整数,0,或负整数),从左到右依次为a1, a2, ..., an,小明可以从中裁剪出连续的一段用来装饰贺卡,而装饰效果就是这一段上各个颜色装饰效果的总和。
小明需要选取装饰效果最好的一段颜色来制作贺卡(取该段颜色数值之和的最大值),当然,如果所有颜色的装饰效果都只能起到负面的作用(即ai<0),小明也可以放弃用彩带来装饰贺卡(获得的装饰效果为0)。
输入格式
数据包括两行:
第一行是一个整数n(1<n<10000),表示彩带上颜色的个数;
第二行有n个整数(每个数介于 -10000 至 10000),它们依次为a1, a2, ..., an。
输出格式
数据只有一个整数,表示贺卡最多能获得多少装饰效果。
输入样例 1
5
-1 2 -1 2 -1
输出样例 1
3
这题其实就用前缀和就可以了,很简单
输入完数组a
后,用前缀和算出每一个数的前缀和,将其存入a
数组中
两个数(下标:i,j)之间(包括自己)的和为:
a[j]-a[i-1]
所以只要双重循环找出最大值是多少就行了
for(int i=2;i<=n;i++)
for(int j=1;j<=i;j++)
ans=max(ans,a[j]-a[i-1]);
由于第二层循环是j<=i
所以复杂度为O(n*(n/2))
还可以承受
C++ Code:
#include<bits/stdc++.h>
using namespace std;
long long a[10001];
typedef long long LL;
long long Max(LL x,LL y)
{
if(x>y)
return x;
return y;
}
int main()
{
int n;
long long len=-1e8;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
a[i]+=a[i-1];
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
len=max(len,a[i]-a[j-1]);
}
len=Max(len,(LL)0);//由于开long long,所以要自己写Max函数
cout<<len;
return 0;
}