基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
N个整数组成的序列a[1],a[2],a[3],…,a[n],从中选出一个子序列(a[i],a[i+1],…a[j]),使这个子序列的和>0,并且这个和是所有和>0的子序列中最小的。
例如:4,-1,5,-2,-1,2,6,-2。-1,5,-2,-1,序列和为1,是最小的。
Input
第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N+1行:N个整数
Output
输出最小正子段和。
Input示例
8 4 -1 5 -2 -1 2 6 -2
Output示例
1
写了个0(n^2)的代码果断超时,然后在网站上看到绿夹克说的一番话,,
这道题先求出前缀和,然后排序,他说的意思是 如果 A,B 不成序列 但是A C成序列,那么B,C一定是比A,C还优的解。。。。顿时一脸蒙蔽。
http://bbs.csdn.net/topics/370106383
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#define maxn 50005
#define inf 0x3f3f3f3f
#define inf 0x3f3f3f
#define clear(a,b) memeset(a,b,sizeof(a))
#define ll long long
using namespace std;
ll a[maxn];
struct node
{
ll sum;
int id;
} ac[maxn];
bool cmp(node a,node b)
{
return a.sum<b.sum;
}
int main()
{
int n,flag=0,x;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
ac[i].sum=ac[i-1].sum+x;
ac[i].id=i;
}
sort(ac+1,ac+1+n,cmp);
ll ans=inf;
for(int i=1;i<=n;i++)
{
if(ac[i].sum>0)
ans=min(ans,ac[i].sum);
if(ac[i].sum-ac[i-1].sum>0&&ac[i].id>ac[i-1].id)
{
ans=min(ans,ac[i].sum-ac[i-1].sum);
}
}
cout<<ans<<endl;
//cout<<sum<<endl;
return 0;
}
/*5
2
5
-1
-12
4*/ // 2