(以“分类:贪心 ==摘要== {{信息题|Max Sum|http://acm.hust.edu.cn/vjudge/contest/view.action?cid{{=}}68572#problem/D|1|100|time=2015-02-06 10:58:51}} *来自...”为内容创建页面) |
小 (→题解: min) |
||
| 第9行: | 第9行: | ||
*瞄了一眼N的范围,发现只能写O(n)的算法,基本就是贪心了。我们都知道求一段a[i]~a[j]的和可以通过求前缀和求得: | *瞄了一眼N的范围,发现只能写O(n)的算法,基本就是贪心了。我们都知道求一段a[i]~a[j]的和可以通过求前缀和求得: | ||
即记<m>s_i</m>=a[1]+a[2]+...+a[i],那么<m>sum_{itoj}=s_j-s_{i-1}</m> | 即记<m>s_i</m>=a[1]+a[2]+...+a[i],那么<m>sum_{itoj}=s_j-s_{i-1}</m> | ||
| − | *显然对于每一个确定的j,<m>s_j</m>是一定的,以他为结尾的最长子序列可以通过计算<m>s_j</m>- | + | *显然对于每一个确定的j,<m>s_j</m>是一定的,以他为结尾的最长子序列可以通过计算<m>s_j</m>-min{<m>s_i</m>}(i<j)来得到,而这是可以之前边录入边处理的。 |
*最后将每一个j所求得的最长子序列求个最大值就好了。详见代码。 | *最后将每一个j所求得的最长子序列求个最大值就好了。详见代码。 | ||
| + | |||
==代码== | ==代码== | ||
{{折叠|1003.cpp代码已折叠 | {{折叠|1003.cpp代码已折叠 | ||
| 题目链接 | 难度等级 | 完成状态 | 完成分数 | 最后编辑时间 | 需要注意 |
|---|---|---|---|---|---|
| Max Sum | ★☆☆☆☆ | 答案正确 | 100 | 2015-02-06 10:58:51 | 无 |
给一串序列,求子序列使得其和最大。
即记=a[1]+a[2]+...+a[i],那么
| 1003.cpp代码已折叠
展开折叠内容
|
|---|
#include<cstdio>
#include<cstring>
#include<climits>
#define _for(i,n) for(int i=1;i<=n;++i)
int sum[120000]={},a[120000]={};
void Work()
{
sum[0]=0;
int n,ans=INT_MIN,ansX,ansY,sumMin=0,sumMinN=0;
scanf("%d",&n);
_for(i,n)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
if(sum[i]-sumMin>ans)
{
ans=sum[i]-sumMin;
ansX=sumMinN+1;
ansY=i;
}
if(sumMin>sum[i])
{
sumMin=sum[i];
sumMinN=i;
}
}
printf("%d %d %d\n",ans,ansX,ansY);
}
int main()
{
int T;
scanf("%d",&T);
_for(i,T)
{
printf("Case %d:\n",i);
Work();
if(i!=T)
printf("\n");
}
}
|