51nod 1065 最小正子段和

Posted 8023spz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1065 最小正子段和相关的知识,希望对你有一定的参考价值。

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,是最小的。
 

输入

第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N+1行:N个整数

输出

输出最小正子段和。

输入样例

8
4
-1
5
-2
-1
2
6
-2

输出样例

1


计算前缀和,每次计算完一个前缀和找前面计算过的比自己小的且相差最小的进行比较最小差。
可以用set,也可以排序。
代码:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n;
int d;
ll sum;
int main() {
    while(~scanf("%d",&n)) {
        ll ans = inf;
        set<ll> s;
        s.insert(0);
        for(int i = 1;i <= n;i ++) {
            scanf("%d",&d);
            sum -= d;
            if(*s.rbegin() > sum) ans = min(ans,*s.upper_bound(sum) - sum);
            s.insert(sum);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<ll,int> pa;
int n,d;
ll sum;
pa p[50000];
int main() {
    while(~scanf("%d",&n)) {
        ll ans = inf;
        for(int i = 1;i <= n;i ++) {
            scanf("%d",&d);
            sum += d;
            p[i] = pa(sum,i);
        }
        p[0] = pa(0,0);
        sort(p,p + n + 1);
        for(int i = 1;i <= n;i ++) {
            if(p[i].second > p[i - 1].second && p[i].first > p[i - 1].first) ans = min(ans,p[i].first - p[i - 1].first);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

以上是关于51nod 1065 最小正子段和的主要内容,如果未能解决你的问题,请参考以下文章

51 Nod 1065 最小正子段和(前缀和)

51Nod1065 最小正子段和

51nod 1065 最小正子段和

51nod-1065:最小正子段和(STL)

51nod-1065 最小正子段和 贪心 + 思维

1065 最小正子段和 二分答案 + 判定