2060 : Minsum Plus(贪心)

走着。

题目描述

题意简单到令人发指!
序列A由N个整数组成,从中选出一个连续的子序列,使得这个子序列的和为正数,且和为所有和大于零的子序列中的最小值.
将这个值输出,若无解,输出no solution。

输入

第一行输入一个正整数N (2 < N < 50000)
第二行输入N个整数

输出

输出最小的正子段和

样例输入

3
-1 2 3

样例输出

1

思路

  • 连续的子序列的和可以用sum[a] - sum[b]表示
  • 符合题目的条件需要满足两个条件
    1. a > b
    2. sum[a] - sum[b] 尽可能的小
  • 综上对sum[] 排序,满足1,2的就是答案

AC

#include<bits/stdc++.h> 
#define ll long long
#define mem(a, b) memset(a, b, sizeof(a)) 
#define N 50005
#define P pair<ll, int>
using namespace std;
P sum[N];
int main() {
//  freopen("in.txt", "r", stdin);
    int n;
    while (~scanf("%d", &n)) {
        mem(sum, 0);
        //构建pair 
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &sum[i].first);
            sum[i].first = sum[i - 1].first + sum[i].first;
            sum[i].second = i;
        }
        //对pair排序 
        sort(sum + 1, sum + 1 + n); 
        ll ans = 1e9;
        if (sum[1].first > 0)   ans = sum[1].first;
        //排序之后保证后大于前,只要满足顺序关系就可以更新 
        for (int i = 2; i <= n; i++) {
        //1 到 N的序列单独判断 
            if (sum[i].first > 0)   ans = min(ans, sum[i].first);
        //  else    continue;
            if (sum[i].second > sum[i - 1].second && sum[i].first != sum[i - 1].first)
                ans = min(ans, sum[i].first - sum[i - 1].first);
        }
        if (ans == 1e9) printf("no solution\n");
        else    printf("%d\n", ans); 
    } 

    return 0;
}

猜你喜欢

转载自blog.csdn.net/henuyh/article/details/80317039