最大连续子序列和

邮差的信 提交于 2020-01-27 05:45:44

下面引入一个编程题理解最大连续子序列和的概念

有一个数组,如1, -5, 8, 3, -4, 15, -8,查找其中连续和最大的相邻串的值。在本例中,最大值为8 + 3 + -4 + 15 = 22.

朴素算法的复杂度为O(n^2),另一种算法如下:

首先假设我们已经找到了最大连续和子串在数组中的起始位置(i)和结束位置(j),其中i <= j,即最大和maxSum = a[i] + a[i + 1] + … + a[j],我们来看看这个子串有什么性质:
1.a[i] > 0,否则我们完全可以去掉a[i]这个元素 而得到一个更大的和;
2.i > 0且a[i - 1] < 0 或 i == 0,下面假设i > 0,这一条性质也是因为如果a[i - 1] > 0的话我们求和时可以加上a[i - 1]这个元素得到一个更大的和;

元素a[i - 1]与它之前的任一元素之间的子串之和sum < 0 ,即对于任何一个m(0 <= m < i - 1),则有a[m] + a[m + 1] + … + a[i - 1] < 0,这条性质同样可以用反证法证明。 如果一时想不明白上面的第三条性质,可以用笔在纸上画画图帮助我们分析。根据第二三条性质,我们感觉 a[i - 1]是一个分界点,最大和的子串要么就在a[i - 1]元素之后,要么就在a[i - 1]之前,最大和的子串不可能跨过a[i - 1]这个点。读者可以仔细想一下这是为什么?还是可以用前面的反证法来思考。

下面举2个例子来看看:第一个例子:假设数组为 1,-2, 3, 4,5,很容易发现-2这个元素满足前述的3个性质:
1.-2 本身是负数
2.-2 + 1 = -1 < 0
所以-2是这样一个分界点,最大和的字串要么在-2之后要么在之前,-2之前的和是1,之后的和sum = 3 + 4 + 5 = 12,所以这个字串的最大和为12。
我们稍微改变一下数组的元素就可以看到最大和字串在分解点之前的情况:

第二个例子:假设数组为 100,-101, 3, 4,5,很容易发现-101这个元素满足前述的3个性质:
-101 本身是负数
-101 + 100 = -1 < 0
所以-101是这样一个分界点,最大和的字串要么在-101之后要么在之前,-101之前的和是100,之后的和sum = 3 + 4 + 5 = 12,所以这个字串的最大和为100。

根据分析我们可以得出结论:只要找到分解点 a[i - 1],最大和的子串要么就在a[i - 1]元素之后,要么就在a[i - 1]之前,最大和的子串不可能跨过a[i - 1]这个点;一个数组中可能有多个这种分界点,但每个分界点都可以把前后完全分开,可以单独算分界点之间的最大和,然后在这些最大和之间取最大值。 假设对于数组a,我们找到了两个分界点a[i]和a[j],那么整个数组的最大字串和就是max(sum(a[0]…a[i-1]), sum(a[i+1]…a[j-1]), sum(a[j+1]…a[len-1]))。

那么怎么去找这个分界点呢?我们从前面的第3个性质可以看出如果a[i-1]是分界点,那么a[0]到a[i - 1]之和必定为负数,所以我们就从a[0]开始逐个往后求和,为了便于描述我们把这个和记为sum,sum第一次变成负数时就是我们要找的分界点。可能您会说sum(a[0]…a[i-1])<0并不代表sum(a[m]…a[i-1])<0 (m < i -1)呀?看看找这个分界点的方法,我们是从第一个元素开始求和,分界点是当sum第一次变成负数时找到的元素,也就是说a[0]到a[m-1]之和必定大于0,记为sum1, a[m]到a[i-1]之和记为sum2, 于是有关系sum1 + sum2 = sum < 0 推出sum2 = sum - sum1 < 0.如下面这个例题:

codeforces 1285B Just Eat It!

Today, Yasser and Adel are at the shop buying cupcakes. There are n cupcake types, arranged from 1 to n on the shelf, and there are infinitely many of each type. The tastiness of a cupcake of type i is an integer ai. There are both tasty and nasty cupcakes, so the tastiness can be positive, zero or negative.
Yasser, of course, wants to try them all, so he will buy exactly one cupcake of each type.
On the other hand, Adel will choose some segment [l,r] (1≤l≤r≤n) that does not include all of cupcakes (he can’t choose [l,r]=[1,n]) and buy exactly one cupcake of each of types l,l+1,…,r.
After that they will compare the total tastiness of the cupcakes each of them have bought. Yasser will be happy if the total tastiness of cupcakes he buys is strictly greater than the total tastiness of cupcakes Adel buys regardless of Adel’s choice.
For example, let the tastinesses of the cupcakes be [7,4,−1]. Yasser will buy all of them, the total tastiness will be 7+4−1=10. Adel can choose segments [7],[4],[−1],[7,4] or [4,−1], their total tastinesses are 7,4,−1,11 and 3, respectively. Adel can choose segment with tastiness 11, and as 10 is not strictly greater than 11, Yasser won’t be happy 😦
Find out if Yasser will be happy after visiting the shop.
Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤104). The description of the test cases follows.
The first line of each test case contains n (2≤n≤105).
The second line of each test case contains n integers a1,a2,…,an (−109≤ai≤109), where ai represents the tastiness of the i-th type of cupcake.
It is guaranteed that the sum of n over all test cases doesn’t exceed 105.
Output
For each test case, print “YES”, if the total tastiness of cupcakes Yasser buys will always be strictly greater than the total tastiness of cupcakes Adel buys regardless of Adel’s choice. Otherwise, print “NO”.
Example
input
3
4
1 2 3 4
3
7 4 -1
3
5 -5 5
output
YES
NO
NO
Note
In the first example, the total tastiness of any segment Adel can choose is less than the total tastiness of all cupcakes.
In the second example, Adel will choose the segment [1,2] with total tastiness 11, which is not less than the total tastiness of all cupcakes, which is 10.
In the third example, Adel can choose the segment [3,3] with total tastiness of 5. Note that Yasser’s cupcakes’ total tastiness is also 5, so in that case, the total tastiness of Yasser’s cupcakes isn’t strictly greater than the total tastiness of Adel’s cupcakes.
题意:
总共有n个糖果,有两个人,一个取全部,一个取片段(不能全取),问最后取片段的最大会不会小于全部的。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long 
#define maxn 100009
ll a[maxn];
int main(){
    int i, j, n, k;
    ll sum, tmp, maxsum, Maxsum;
    char c;
    scanf("%d",&k);
    while(k--){
        scanf("%d",&n);
        sum = 0;
        for(i= 1; i<=n; i++){
            scanf("%lld",&a[i]);
            sum += a[i];
        }
        ll maxh = a[1];
        maxsum = a[1];
        for(i = 2; i <= n-1; i++){
            if(maxh <= 0)  maxh = a[i];
            else maxh += a[i];
            maxsum = max(maxsum,maxh);
        }
        maxh = a[2];Maxsum = a[2];
        for(i = 3; i <= n; i++){
            if(maxh <= 0)  maxh = a[i];
            else maxh += a[i];
            Maxsum = max(Maxsum,maxh);
        }
        if(max(maxsum,Maxsum) >= sum) printf("NO\n");
        else printf("YES\n");
    }


}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!