51Nod - 1065 最小正子段和

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1065

知识点:  (void)

解题思路:

  先记录下序列的前缀和及对应的位置,然后根据前缀和从小到大排序,找出合理的两个前缀和之差最小的即可(所谓 “合理” 即是指大的前缀和所对应的位置肯定要在小的前缀和的后面,这样二者之差才是这两个位置之间的子段和)。有几个点需要注意:1、题目要求的是正子段和,所以除了让答案尽可能小之外还要大于0;2、要添加一个前缀和为0、位置为0的项,否则无法取序列中的单项。

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<ll,int> P;
 5 const int maxn = 50000+4;
 6 const ll inf=0x7fffffff;
 7 ll a[maxn];
 8 P sum[maxn];
 9 int main(){
10     int N;
11     scanf("%d",&N);
12     for(int i=1;i<=N;i++)    scanf("%lld",&a[i]);
13     sum[0]=make_pair(0,0);
14     for(int i=1;i<=N;i++)    sum[i]=make_pair(sum[i-1].first+a[i],i);
15     sort(sum,sum+N+1);
16     ll ans=inf;
17     for(int i=0;i<=N;i++){
18         for(int j=i+1;j<=N;j++){
19             if(sum[j].first-sum[i].first>=ans)  break;
20             if(sum[j].second>sum[i].second&&sum[j].first-sum[i].first>0)
21                 ans=sum[j].first-sum[i].first;
22         }
23     }
24     printf("%lld\n",ans);
25 
26     return 0;
27 }

 

posted @ 2018-01-15 23:22  Blogggggg  阅读(135)  评论(0编辑  收藏  举报